bshaffer / oauth2-server-php

A library for implementing an OAuth2 Server in php
http://bshaffer.github.io/oauth2-server-php-docs
MIT License
3.26k stars 953 forks source link

redirect_uri_mismatch #188

Open cristian-v opened 11 years ago

cristian-v commented 11 years ago

I was implementing the library and i've try to use a an url that has a user and password in the url, i've send the data as urlencoded value but when it gets to AuthorizeCode GrantType the flow goes on the true side of if(!$request->request('redirect_uri') || urldecode($request->request('redirect_uri')) != $authCode['redirect_uri']) { . I've check and to make sure that the url is receive as a normal url I have to send the value of redirect urlencoded twice. example of url: http://oauth:oauth++@localhost/oauth/redirect.php

F21 commented 11 years ago

Could you post a simple php script to reproduce this? This makes it easier for us to investigate and push a fix :smile:

cristian-v commented 11 years ago

The request to receive a token from an authorization code.

Exchange the token

    <form action="http://localhost/server/oauth/token/" method="post" enctype="multipart/form-data" >
        <input type="hidden" name="grant_type" value="authorization_code">
        <input type="hidden" name="code" value="fd853fa66e10f1d891ea83e2335412fed0a9c4fe">
        <input type="hidden" name="client_id" value="Cris">
        <input type="hidden" name="client_secret" value="Experimenting">
        <input type="hidden" name="redirect_uri" value="<?php echo urlencode('http://oauth:oauth++@localhost/client/redirect.php'); ?>">
        <input type="submit" name="submit" value="Exchange auth with token">
    </from>

The integration of the library

//adding the autoloader
require_once('OAuth2/vendor/autoload.php');

class Oauth2Library {
    public $dns;
    public $user;
    public $pass;

    public function token(){
        // creating the server
        $this->setup();

        // Handle a request for an OAuth2.0 Access Token and send the response to the client
        $this->server->handleTokenRequest(OAuth2_Request::createFromGlobals(), new OAuth2_Response())->send();
        return;
    }

    public function authorizeFormSubmit()
    {
        //create the server
        $this->setup();

        // check the form data to see if the user authorized the request
        $authorized = true;//(bool) $this->request->get('authorize');

        // call the oauth server and return the response
        return $this->server->handleAuthorizeRequest(OAuth2_Request::createFromGlobals(), new OAuth2_Response(), $authorized)->send();
    }

    public function setup(){
        // $dsn is the Data Source Name for your database, for exmaple "mysql:dbname=my_oauth2_db;host=localhost"
        $this->storage = new OAuth2_Storage_Pdo(array('dsn' => $this->dsn, 'username' => $this->user, 'password' => $this->pass));

        // Pass a storage object or array of storage objects to the OAuth2 server class
        $this->server = new OAuth2_Server($this->storage);

        // Add the "Authorization Code" grant type
        $this->server->addGrantType(new OAuth2_GrantType_AuthorizationCode($this->storage));
        return;
    }

}

The sql with the oauth client

INSERT INTO oauth.oauth_clients ( client_id , client_secret , redirect_uri ) VALUES ( 'Cris', 'Experimenting', 'http://oauth:oauth++@localhost/client/redirect.php' );

bshaffer commented 11 years ago

This may have to do with urldecode not being called before the redirect_uri is stored, but I'm not sure.

@cristian-osf consider writing a Unit Test that expresses the error in this case. That will help us with the fix.

cristian-v commented 11 years ago

The storage.json file

{ "authorization_codes": { "testcode": { "client_id": "Test Client ID", "user_id": "1", "redirect_uri": "http://user:pass++@brentertainment.com:2222/authorize/cb?auth_type=oauth", "expires": "9999999999" } } }

The function that tests this code:

public function testInvalidRedirectUri(){
        $server = $this->getTestServer();
        $request = TestRequest::createPost(array(
            'grant_type' => 'authorization_code', // valid grant type
            'code'       => 'testcode',
            'client_id' => 'Test Client ID', // valid client id
            'client_secret' => 'TestSecret', // valid client secret
            'redirect_uri' => 'http://user:pass++@brentertainment.com:2222/authorize/cb?auth_type=oauth',
            'scope' => 'clientscope1 clientscope2 scope1 scope2 scope3'
        ));
        $server->handleTokenRequest($request, $response = new Response());
        $this->assertTrue($response instanceof Response);
        $this->assertEquals($response->getStatusCode(), 200);
        $this->assertNull($response->getParameter('error'));
        $this->assertNull($response->getParameter('error_description'));
        $this->assertNotNUll($response->getParameter('access_token'));
        $this->assertNotNUll($response->getParameter('expires_in'));
        $this->assertNotNUll($response->getParameter('token_type'));
    }