Welcome Guest, Not a member yet? Register   Sign In
[SOLVED] HTTP Digest in CI for REST
#1

[eluser]Phil Sturgeon[/eluser]
I am trying to complete a REST implementation that other than digest auth is perfect!

Below is a link to my testing CodeIgniter setup. In there is controllers/rest_test.php which will make calls to example_api.php using the REST.php client library, which in turn uses a modified version of my Curl.php library.

http://philsturgeon.co.uk/uploads/rest.zip

If anyone can help with this I will love you and perhaps slip you a financial thanks towards payday as this has started to give me a damn migrane.

HTTP Basic works PERFECTLY. Digest does not work for sh*t.

The issue is that the expected responce we build, and the responce provided by digest just do not match, yet all the data is there and is being put together correctly. PLEASE somebody fix this.
#2

[eluser]Phil Sturgeon[/eluser]
The code that does the digest checking is in rest/application/libraries/REST_Controller.php under _prepareDigestAuth()
#3

[eluser]tomcode[/eluser]
Try this one :
Code:
private function _prepareDigestAuth()
    {
        $digest = NULL;
        $nonce = uniqid();
        
        // We need to test which server authentication variable to use
        if(isset($_SERVER['PHP_AUTH_DIGEST']))
        {
            $digest = $_SERVER['PHP_AUTH_DIGEST'];
        }
        
        elseif(isset($_SERVER['HTTP_AUTHORIZATION']))
        {
            $digest = $_SERVER['HTTP_AUTHORIZATION'];
        }
        
        else
        {
            $digest = "";
        }
        
        // If there was no digest, show login
        if (empty($digest))
        {
            $this->_forceLogin($nonce);
        }
        
        preg_match_all('@(username|nonce|uri|nc|cnonce|qop|response)'.
                    '=[\'"]?([^\'",]+)@', $digest, $t);
        $digest_parts = array_combine($t[1], $t[2]);
            
        if ( !$this->_checkLogin($digest_parts['username']) )
        {
            $this->_forceLogin($nonce);
        }
        
        $valid_logins =& $this->config->item('rest_valid_logins');
        $valid_pass = $valid_logins[$digest_parts['username']];
        
        // Based on all the info we gathered we can figure out what the response should be
        $A1 = md5($digest_parts['username'] . ':' . $this->config->item('rest_realm') . ':' . $valid_pass);
        $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$digest_parts['uri']);
        
        $valid_response = md5($A1.':'.$digest_parts['nonce'].':'.$digest_parts['nc'].':'.$digest_parts['cnonce'].':'.$digest_parts['qop'].':'.$A2);
            
        if ($digest_parts['response'] != $valid_response)
        {
            $this->_forceLogin($nonce);
        }

    }
#4

[eluser]Phil Sturgeon[/eluser]
Actually you were pretty damn close, using $_SERVER['REQUEST_METHOD'] would have worked.

The error I made was forgetting I used strtolower() to get the method (GET, POST, PUT, etc) so all I needed to do was strtoupper it which would give me the same result as using $_SERVER['REQUEST_METHOD'] anyway!

This is now done and with a little help from Adam Griffiths and Paul Charter we have a fairly tested and useable working system for non-auth, basic and digest.

I am in the process of making up some test controllers and then this will be screencast exampled and released.
#5

[eluser]Phil Sturgeon[/eluser]
The code is up on GitHub now and works perfectly with no auth, basic or digest as far as I can tell.

http://github.com/philsturgeon/codeigniter-restserver

Not releasing it just yet as recently PUT and POST have stopped working properly, but it will be released soon. There is an example controller in there and the default controller has a few example links. User guide coming soon after PUT and POST are fixed.
#6

[eluser]Unknown[/eluser]
Hi ,I have a problem with PUT and POST
Does this fixed?
when I insert a row to database,I got two rows:

username password
0 0
lucky 111222
why?
#7

[eluser]Unknown[/eluser]
A small gentle note.

I was having problem with digest authentication using CURL. I made some tweak and override the method of the request by assigning

Code:
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, array(
‘_method’ => ‘put’,
‘id’ => $id,
));
What I am doing is I am always doing a post through curl and with ‘_method’ I am overriding the default method. The rest controller detects the request method so in the example above it will detect request method as PUT and is assigned to $this->request->method as put.

In the function _prepare_digest_auth at line no 734
Code:
$A2 = md5(strtoupper($this->request->method) . ‘:’ . $digest['uri']);

It will supply put as the request and not post while curl posted the data. It will fail to authenticate the user.
After I modified this to be
Code:
$A2 = md5($this->input->server(‘REQUEST_METHOD’) . ‘:’ . $digest['uri']);
it all worked well.
Now I have all authentication methods working.
Thanks.
Neeraj




Theme © iAndrew 2016 - Forum software by © MyBB