GithubHelp home page GithubHelp logo

bshaffer / oauth2-server-php Goto Github PK

View Code? Open in Web Editor NEW
3.2K 210.0 945.0 1.42 MB

A library for implementing an OAuth2 Server in php

Home Page: http://bshaffer.github.io/oauth2-server-php-docs

License: MIT License

PHP 100.00%

oauth2-server-php's Introduction

oauth2-server-php's People

Contributors

adambutler avatar adamz avatar afilippov1985 avatar arul- avatar bojanz avatar bshaffer avatar dallasvogels avatar daohoangson avatar darrylkuhn avatar davidkuridza avatar dazz avatar dsquier avatar f21 avatar fauguste avatar itskingori avatar jacketbg avatar javigs avatar julien-c avatar maks3w avatar mathroc avatar phindmarsh avatar rjmackay avatar sarciszewski avatar snapshotpl avatar stefanaxelsson avatar svycka avatar tmotyl avatar tom-park avatar trickleup avatar wilt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oauth2-server-php's Issues

refresh_token being granted in Client Credentials Grant

In testing OAuth2_Storage_RefreshTokenInterface, a refresh_token is being returned when using the Client Credentials Grant. It should probably be removed from this grant type to better adhere to http://tools.ietf.org/html/rfc6749#section-4.4.3

4.4.3.  Access Token Response

   If the access token request is valid and authorized, the
   authorization server issues an access token as described in
   Section 5.1.  A refresh token SHOULD NOT be included.

Code from an example call:

$storage = new PDO('mysql:dbname=account;host=localhost', 'oauth', 'oauth');
$server = new OAuth2_Server($storage);
$server->addGrantType(new OAuth2_GrantType_ClientCredentials($storage));

$request = OAuth2_Request::createFromGlobals();
$token = $server->grantAccessToken($request)

echo json_encode($token);

With the following response:

{"access_token":"ce7f0d2cce0e9dc0e6f4d6ed24c5def1afdea5c6","expires_in":3600,"token_type":"bearer","scope":null,"refresh_token":"a7db8c2b2bdf4319d6233db394979e89c5809ffe"}

[PHP 5.4.7] Warning: curl_setopt_array(): CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir

Warning: curl_setopt_array(): CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir

emulation CURLOPT_FOLLOWLOCATION on php alternative curl_exec

function curl_redir_exec($ch)  
{  
    static $curl_loops = 0;  
    static $curl_max_loops = 20;  
    if ($curl_loops   >= $curl_max_loops)  
    {  
    $curl_loops = 0;  
        return FALSE;  
    }  
    curl_setopt($ch, CURLOPT_HEADER, true);  
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  
    $data = curl_exec($ch);  
    list($header, $data) = explode("\r\n\r\n", $data, 2);  
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);  
    if ($http_code == 301 || $http_code == 302)  
    {  
    $matches = array();  
        preg_match('/Location:(.*?)\n/', $header, $matches);  
    $url = @parse_url(trim(array_pop($matches)));  
        if (!$url)  
    {  
        //couldn't process the url to redirect to  
        $curl_loops = 0;  
        return $data;  
        }  
    $last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));  
    if (!$url['scheme'])  
        $url['scheme'] = $last_url['scheme'];  
    if (!$url['host'])  
        $url['host'] = $last_url['host'];  
    if (!$url['path'])  
        $url['path'] = $last_url['path'];  
    $new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . ($url['query']?'?'.$url['query']:'');  
    curl_setopt($ch, CURLOPT_URL, $new_url);  
    //debug('Redirecting to', $new_url);  
    return curl_redir_exec($ch);  
    }   else {  
        $curl_loops=0;  
        return $data;  
        }  
}  

2 legged OAuth

I just came across your library and would like to implement it into my application to support OAuth 2.

I am looking to implement 2-legged OAuth for server-to-server authorization which means that I won't have to send a token with each request to my application's API.

Edit: Looks like the above applies to OAuth 1. In OAuth 2, all I see is an Authorization: OAuth ya29.afa3fsadfaf
header.

I am still looking through the source, but does this library support 2-legged OAuth (processing request without a token)? If so, how is it implemented?

getAccessTokenData returned values

I understand that the getAccessTokenData exists to return the Access Token, however I'm looking for a way to get ALL of the Access Token Data as the name suggests. Is there a way to do that I don't see? Or could the function be renamed to something closer to what the function actually returns, i.e. just getAccessToken?

Add note to README about implicit flow security

The implicit flow is less secure than the authorization code flow, neither the spec or any other resources attempt to hide that.

A potential problem revolves around mistakenly using OAuth2 not just for authorization, but for authentication as well.
An attack is described in http://homakov.blogspot.com/2012/08/oauth2-one-accesstoken-to-rule-them-all.html
and can be resolved by implementing an additional call to validate the access token after it has been received (send the token and a client id, get a status and a list of scopes back).

I think it would make sense to have a note in the README about this.

As the people providing the library (and Drupal integration in my case), we are responsible if people shoot themselves in the foot with it.

Another related resource: http://homakov.blogspot.com/2013/03/oauth1-oauth2-oauth.html

Better Handling of DateTimes

DateTimes are currently passed back in unix timestamp format. We should be able to handle multiple datetime formats, or at least the DateTime php class.

In addition, we should consider adding typehinting to the storage interfaces, i.e. DateTime $expires. This will remove ambiguity

$tokenData must be an array, boolean given in UserCredentials.php

I receive the following error when trying to call the "User Credentials" grant type (i.e., "Resource Owner Password Credentials Grant" per the OAuth spec at http://tools.ietf.org/html/rfc6749#section-4.3):

PHP Catchable fatal error: Argument 1 passed to OAuth2_GrantType_UserCredentials::validateTokenData() must be an array, boolean given, called in /home/oauth/www/lib/oauth2-server-php-develop/src/OAuth2/Controller/GrantController.php on line 133 and defined in /home/oauth/www/lib/oauth2-server-php-develop/src/OAuth2/GrantType/UserCredentials.php on line 41

Doing some investigation I found that getTokenDataFromRequest() in UserCredentials.php is returning $tokenData as a boolean, but validateTokenData() expects an array.

In order to get it working, I made the following change to getTokenDataFromRequest() in UserCredentials.php:

Replace:

return $tokenData;

With:

// the only piece to pull is the "scope" parameter
$scope = $request->headers('REQUEST_METHOD') == 'POST' ? $request->request('scope') : $request->query('scope');
return array(
    "scope" => $scope
); 

This behavior follows that in the "Client Credentials" grant type, which I was able to get working out of the box. I'm not sure this is the ideal solution, but it's working.

BTW, I tested all this on the latest development branch.

Get Scope from Request does not work in /authorize post

When the Resource Owner clicks on the 'Authorize' Button the previous queryString will be added to the url and the form is sent with POST to the server.

template:

<form action="{{ path('oauth2_authorize_post') ~ '?' ~ app.request.queryString }}" method="post">

So depending on the REQUEST_METHOD does not work in this case as the scope will be in the GET parameters.

https://github.com/bshaffer/oauth2-server-php/blob/develop/src/OAuth2/Scope.php#L51-L54

OAuth2_Server->getClientCredentials() problem

At the token endpoint, using the client credentials grant flow, I'm calling the OAuth2_Server function getClientCredentials(), that defers to the GrantController and in turn calls getClientCredentials() on the grant controller. Problem is that the grant controller doesn't implement getClientCredentials(). It seems the logic to extract the credentials is in OAuth2_ClientAssertionType_HttpBasic, and I can just instantiate that class and get the credentials that way - but that doesn't seem like best practice. Any advice?

PSR-2 standards

I have identified the following issues where the project does not adhere to psr-2 standards.

! The class OAuth2_GrantType_AuthorizationCodeInterface in /www/oauth2-server-php/src/OAuth2/ResponseType/AuthorizationCodeInterface.php does not match the file path according to PSR-0 rules

And this is a list of files that also require fixing:

   1) src/OAuth2/Autoloader.php
   2) src/OAuth2/Controller/AccessController.php
   3) src/OAuth2/Controller/AccessControllerInterface.php
   4) src/OAuth2/Controller/AuthorizeController.php
   5) src/OAuth2/Controller/AuthorizeControllerInterface.php
   6) src/OAuth2/Controller/GrantControllerInterface.php
   7) src/OAuth2/GrantType/ClientCredentials.php
   8) src/OAuth2/GrantType/RefreshToken.php
   9) src/OAuth2/GrantTypeInterface.php
  10) src/OAuth2/Request.php
  11) src/OAuth2/RequestInterface.php
  12) src/OAuth2/Response/AuthenticationError.php
  13) src/OAuth2/Response/Error.php
  14) src/OAuth2/Response/ProviderInterface.php
  15) src/OAuth2/Response/Redirect.php
  16) src/OAuth2/Response.php
  17) src/OAuth2/ResponseType/AccessToken.php
  18) src/OAuth2/ResponseType/AccessTokenInterface.php
  19) src/OAuth2/ResponseType/AuthorizationCode.php
  20) src/OAuth2/ResponseType/AuthorizationCodeInterface.php
  21) src/OAuth2/ResponseTypeInterface.php
  22) src/OAuth2/Server.php
  23) src/OAuth2/Storage/AccessTokenInterface.php
  24) src/OAuth2/Storage/AuthorizationCodeInterface.php
  25) src/OAuth2/Storage/ClientCredentialsInterface.php
  26) src/OAuth2/Storage/ClientInterface.php
  27) src/OAuth2/Storage/RefreshTokenInterface.php
  28) src/OAuth2/Storage/UserCredentialsInterface.php
  29) src/OAuth2/TokenType/Bearer.php
  30) src/OAuth2/TokenType/MAC.php
  31) src/OAuth2/TokenTypeInterface.php
  32) src/OAuth2/Util.php
  33) test/bootstrap.php
  34) test/lib/OAuth2/Request/TestRequest.php
  35) test/lib/OAuth2/Storage/Bootstrap.php
  36) test/OAuth2/AutoloadTest.php
  37) test/OAuth2/GrantType/AuthorizationCodeTest.php
  38) test/OAuth2/GrantType/ClientCredentialsTest.php
  39) test/OAuth2/GrantType/RefreshTokenTest.php
  40) test/OAuth2/GrantType/UserCredentialsTest.php
  41) test/OAuth2/RequestTest.php
  42) test/OAuth2/ResponseTest.php
  43) test/OAuth2/Server/Access/BasicValidationTest.php
  44) test/OAuth2/Server/Authorize/BasicValidationTest.php
  45) test/OAuth2/Server/Authorize/CodeTest.php
  46) test/OAuth2/Server/Authorize/ImplicitTest.php
  47) test/OAuth2/Server/Grant/BasicValidationTest.php
  48) test/OAuth2/Storage/PdoTest.php

Util.php

After adding the JWT Authorization Grant, we now have a folder called Utils: /OAuth2/Utils. There also remains a Util.php: /OAuth2/Util.php

How do you feel about refactoring Util.php and moving it under /Utils? We could also rename the class to something that's more descriptive as well.

Add Response parameter to server methods

Similar to kriswallsmith/Buzz, we'd like to submit the response as part of the request. This will make for a much cleaner Controller layer, and also allow for dependency injection, which is really not currently possible without undergoing a massive amount of pain.

It would be helpful to be able to map the database column names for table "user"?

My "user" table doesn't have primary column named "user_id" , it is called "id" . Right now i have changed query

SELECT * from user_table

to

SELECT *, id as user_id from user_table

so that user_id is updated correctly in in access_token table. It woud be helpful if we can via configuration map the column name for "user" table.

The correct table structure

Sorry but I can not understand what is the right database structure to use!
This class OAuth2_Storage_Pdo understand that you must have 4 tables:

  • oauth_clients
  • oauth_access_tokens
  • oauth_authorization_codes
  • oauth_users
    but how they are structured? With what fields and what kind?
    Not familiar with the framework used in the demo and I can not understand the flow of the process! : S
    Thanks

Checking scope on access token creation

Currently, storages implement getAccessToken() and setAccessToken() to get and save access tokens.

In createAccessToken in OAuth2_ResponseType_AccessToken.php:

  • The state of whether the access token was successfully written to storage is not checked.
  • The scope that is requested is simply returned back to the client. However, the spec says that if the client requests a scope to be included with the token, we can reject the request if the scope is invalid, or alternatively, we can send the scope we have assigned them in the response:
   The authorization server MAY fully or partially ignore the scope
   requested by the client based on the authorization server policy or
   the resource owner's instructions.  If the issued access token scope
   is different from the one requested by the client, the authorization
   server MUST include the "scope" response parameter to inform the
   client of the actual scope granted.

   If the client omits the scope parameter when requesting
   authorization, the authorization server MUST either process the
   request using a pre-defined default value, or fail the request
   indicating an invalid scope.  The authorization server SHOULD
   document its scope requirements and default value (if defined).

I propose that we add the following enhancements to createAccessToken():

  • Check to see if access token was successfully written to storage. If not, return an error message to the client.
  • Let implementers process the scope in setAccessToken() of the storage driver and return a list of scopes that is assigned to the token if successfully. If write to storage was unsuccessful, return a false.
  • createAccessToken()` then sends the actual scope set on the server back to the client.

Let me know what you think :)

Harden default security

OAuth2 is insecure by default.
This library does a good job of closing off many attack vectors.

I did notice two things that could be better by default.
Taken from: http://homakov.blogspot.com/2012/08/saferweb-oauth2a-or-lets-just-fix-it.html

Suggestions:

  1. Change validateRedirectUri() to validate the urls by exact match.
  2. Require state by default (change enforce_state to TRUE).

The article also suggest making allow_implicit a per-client setting. I don't need this on my side because I have the notion of different "contexts" on Drupal side, so all similar clients are grouped, but it might make sense for the library itself.
In any case, the two suggestions above would be easy wins for better security (I like the phrase "if it's insecure by default, then it's insecure")

Authorize to make a change to entry?

Hi,

I'm loving this git! I have one thing which I'd really like to do with OAuth2 but I haven't found an option yet. Is it possible to have the OAuth2 client authorize changes to the information on the server?
For example, imagine Lock'dIn has profile information ie {"name":["Robert"]}. Is it possible to change the name saved in Lockd'In through DemoApp (So authorize a change to credentials ie 'DemoApp is requesting to set your Name to Bob')?

Thank you!

createAccessToken() - Not expiring or returning existing tokens

I noticed that when we use the same client_id and client_secret to request a token on behalf of a user (say, [email protected]), a new token is generated even though a token already exists. In addition, the old token is not deleted.

I have been going through the spec, but could not find anything regarding this.

Is this the correct behaviour?

Cheers :)

PDO, PGSQL and Development

Hi Brent, Currently rolling out some Oauth2 stuff here for various GIS end applications. We do have our own rudimentary Oauth2 in house server but I'm looking to ditch this in favour of something a little further down the development line. As all our stuff is GIS we're very much postgres/postgis folks. I'm immediately hitting some incompatibilities when using PDO/pgsql with your stuff, initially in data escaping in SQL commands. What I'm going to do is update some of this stuff to use data binding to fix these issues and at the same time improve the SQL injection vulnerabilities. Are you interested in getting these changes into your source or am I heading off alone down my own fork?

Ta,

Andy Shelley.

Granting a new refresh_token when refreshing a token

When submitting a request for an access_token using either the 'Authorization Code' or 'Resource Owner Password Credential' grant, a refresh_token is provided. An example from the latter:

{"access_token":"df680f467c3a410ef615dad7cc480de547467144","expires_in":3600,"token_type":"bearer","scope":null,"refresh_token":"9a74026f2be71d8e81f13d5d607217d93c1ff52d"}

When using the refresh_token from above to request a new access_token, a new refresh_token is not provided, i.e.,

{"access_token":"4a3812a0638e9d4120ba3721e1a9158e72eacacb","expires_in":3600,"token_type":"bearer","scope":null}

While the spec does not strictly require a refresh_token be granted in this case, is it possible to do this?

Thanks much!

Make acceptance of client_secret in request body optional

For client authentication, OAuth2_ClientAssertionType_HttpBasic looks for client_secret in POST data if Basic authentication wasn't used. This is allowed by the spec, but it is optional for authorization servers to support.

http://tools.ietf.org/html/rfc6749#section-2.3.1

Alternatively, the authorization server MAY support including the
client credentials in the request-body[...]

Including the client credentials in the request-body using the two
parameters is NOT RECOMMENDED and SHOULD be limited to clients unable
to directly utilize the HTTP Basic authentication scheme (or other
password-based HTTP authentication schemes).

I would like to disable support for it in my authorization server without extending/overriding OAuth2_ClientAssertionType_HttpBasic or implementing my own OAuth2_ClientAssertionTypeInterface.

Accepting client_secret in POST should be configurable somehow. Even better, it could be added to the client details so it can be accepted optionally per client.

Side note: The reference to http://tools.ietf.org/html/rfc6749#section-2.4.1 in OAuth2_ClientAssertionType_HttpBasic is incorrect; it should be 2.3.1.

Enhancing scopes

I have been using the new ScopeInterface and the Storage_ScopeInterface and love the flexibility it offers.

I think it can be slightly enhanced to allow more flexibility.

In an application I am building, 2 grant types are allowed: JWT Authorization Grant and Authorization Code. The JWT type is used for service accounts, so should have access to a set of scopes that are used for administrating the system. Authorization Code grants would not have access to these scopes.

Similarly, it is also possible to have a system where different client_ids have access to a different set of scopes.

I think it will be beneficial if we can extend the ScopeInterface to include a validateScope($client_id, $user_id, array $scope = null).

This would be called by createAccessToken() in the AccessToken response type. Essentially, the scope, client_id and user_id is passed to validateScope.

validateScope then looks up the scopes that are available for the client_id and user_idand perhaps the grant type (not sure how this should be done yet). Perhaps instead of passing the client_id and user_id, we can pass in the $request, so the method gets access to all information about the request.

validateScope would then validate the scopes and return an array containing only the valid scopes (invalid or not allowed scopes are removed). This can then be sent back to the client:

$token = array(
            "access_token" => $this->generateAccessToken(),
            "expires_in" => $this->config['access_lifetime'],
            "token_type" => $this->config['token_type'],
            "scope" => $this->scopeUtil->validateScope($request)
        );

Let me know what you think :)

SAML client and authorization grants

Was just reading about SAML and found that they can also be used to authenticate and authorize OAuth 2 tokens.

The flow seems to be quite similar to how JWT works, so we should be quite familiar with it.

IETF Draft: http://tools.ietf.org/html/draft-ietf-oauth-saml2-bearer-16

This is not a must have or anything urgent, but would be nice to implement when any of us have some extra time. The flow should be very similar if not identical to the flow for JWT tokens, so it shouldn't be too complicated.

Interestingly, it also has a client authentication mode similar to JWT's client authentication in #27, so perhaps we can look at a general way to abstract the AuthorizationCode grant type to support JWTs and SAML.

Rename Controllers to Match Spec

This is a picky change, but the spec names the controllers Resource, Token, and Authorize, while we have named them Access, Grant, and Authorize.

Let's name them to match the spec!

One-Legged OAuth with OAuth2

I received this question and thought it deserved a public answer:

Can the provider component from your oauth2-server-demo be used for two-legged, non-interactive authentication?

We need to utilize two-legged auth for a fairly traditional client-server model between our various sites and the central authentication server.

getAccessTokenData should take the $request object as a parameter

There's to my knowledge no public way to get the $token_param and $scope required, without hardcoding and assume we're using a bearer token.
AccessController could do the same logic as verifyAccessToken for getAccessTokenData as it has access to the protected $tokenType.

Unless I am really missing something...

Add MAC Token Type

This is a big enhancement, but needs to be done, as MAC tokens are the most secure way to implement an OAuth2 Server, and do not rely fully on SSL for their protection.

Question: how would you persist access tokens

Hi guys,

I've noticed every time a user uses the authorization grant, a new authorization code is generated and thus a new access token is returned, regardless if that user already had a valid access token.
On Facebook, if you have authorized the app and have a valid token, that token is returned to you after the usual transparent redirects...

How would you go about implementing something like that?

Thanks

Cédric

Better README

Add the three main request types to the readme, and outline the main methods involved. Also, link to a blog post/tutorial once created

Make OAuth2_Storage_Pdo Class extendable

Is ist possible to change scope of properties $db and $config in "OAuth2_Storage_Pdo" from "private" to "protected" so that people can extend the class and implement their own "getUser" function. For example for this usecase: #68

Unable to retrieve access_token using getAccessTokenParameter with Bearer Authorization

Unable to retrieve access_token using getAccessTokenParameter from Bearer.php. For example, an HTTP POST with Header:

Authorization: Bearer 713eca9cb36f9c1be6b86d5dc242b5bb00c88598

is sent and a request is created:

$request = OAuth2_Request::createFromGlobals();

Doing a var_dump of $request:

...
    [server] => Array
        (
            [REDIRECT_HTTP_AUTHORIZATION] => Bearer 713eca9cb36f9c1be6b86d5dc242b5bb00c88598
            [REDIRECT_STATUS] => 200
            [HTTP_AUTHORIZATION] => Bearer 713eca9cb36f9c1be6b86d5dc242b5bb00c88598
            [HTTP_HOST] => 192.168.2.13
            [HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0
            [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
            [HTTP_ACCEPT_LANGUAGE] => en-US,en;q=0.5
            [HTTP_ACCEPT_ENCODING] => gzip, deflate
            [HTTP_DNT] => 1
            [HTTP_CONNECTION] => keep-alive
            [CONTENT_TYPE] => application/x-www-form-urlencoded; charset=UTF-8
            [CONTENT_LENGTH] => 61
            [HTTP_COOKIE] => PHPSESSID=cofdhm7vqquplkbvjjf9ofutp2
            [HTTP_PRAGMA] => no-cache
            [HTTP_CACHE_CONTROL] => no-cache
            [PATH] => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
            [SERVER_SIGNATURE] => <address>Apache/2.2.22 (Ubuntu) Server at 192.168.2.13 Port 80</address>

            [SERVER_SOFTWARE] => Apache/2.2.22 (Ubuntu)
            [SERVER_NAME] => 192.168.2.13
            [SERVER_ADDR] => 192.168.2.13
            [SERVER_PORT] => 80
            [REMOTE_ADDR] => 192.168.2.12
            [DOCUMENT_ROOT] => /var/www
            [SERVER_ADMIN] => webmaster@localhost
            [SCRIPT_FILENAME] => /var/www/index.php
            [REMOTE_PORT] => 56430
            [REDIRECT_URL] => /admin/addclient
            [GATEWAY_INTERFACE] => CGI/1.1
            [SERVER_PROTOCOL] => HTTP/1.1
            [REQUEST_METHOD] => POST
            [QUERY_STRING] =>
            [REQUEST_URI] => /admin/addclient
            [SCRIPT_NAME] => /index.php
            [PHP_SELF] => /index.php
            [REQUEST_TIME] => 1356741875
        )
...
    [headers] => Array
        (
            [AUTHORIZATION] => Bearer 713eca9cb36f9c1be6b86d5dc242b5bb00c88598
            [HOST] => 192.168.2.13
            [USER_AGENT] => Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0
            [ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
            [ACCEPT_LANGUAGE] => en-US,en;q=0.5
            [ACCEPT_ENCODING] => gzip, deflate
            [DNT] => 1
            [CONNECTION] => keep-alive
            [CONTENT_TYPE] => application/x-www-form-urlencoded; charset=UTF-8
            [CONTENT_LENGTH] => 61
            [COOKIE] => PHPSESSID=cofdhm7vqquplkbvjjf9ofutp2
            [PRAGMA] => no-cache
            [CACHE_CONTROL] => no-cache
        )
...

I can get it working by changing $request to look for the AUTHORIZATION in ->$headers from ->server, i.e.,

public function getAccessTokenParameter(OAuth2_RequestInterface $request)
{
    $headers = $request->headers('AUTHORIZATION');

By working, I mean the following returns a value for $access_token:

$bearer = new OAuth2_TokenType_Bearer();
$access_token = $bearer->getAccessTokenParameter($request);

My question-- am I implementing this incorrectly? Please note the following RewriteRule was added to .htaccess to allow for PHP parsing of Authorization other than Basic or Digest:

RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Superfluous "WWW-Authenticate"

src/OAuth2/Response/AuthenticationError.php:11
Superfluous "WWW-Authenticate".
Resulting header is: "WWW-Authenticate: WWW-Authenticate: bearer realm=Service"

Several problems in TokenController::grantAccessToken().

  1. It gets $tokenData using $grantType->getTokenDataFromRequest().
    However, that method name is non-sensical. Let's see what gets returned:
  • For the authorization_code grant type, the authorization code is fetched from storage.
  • For the refresh_token grant type, the refresh token is fetched from storage.
  • For the password grant type, user data is fetched from storage.
  • For the client_credentials grant_type, an array with just the scope from the request is returned.

So the "FromRequest' part is mostly untrue, the method could use a better name.

  1. When using the client_credentials grant type, scope is not validated.
    $tokenData['scope'] is fetched from the request by getTokenDataFromRequest().
    $scope is also fetched from request by:
    $scope = $this->scopeUtil->getScopeFromRequest($request);
    So the scope check compares two same values:
    if (!is_null($scope) && !$this->scopeUtil->checkScope($scope, $tokenData["scope"])) {
    and doesn't actually validate anything, an invalid scope is set on the issued access token.

  2. When using the password grant type, the requested scope is never set (the default scope is set instead).
    Since the user credentials returned from getTokenDataFromRequest() contain no scope, the default scope is assigned every time.

Maybe the scope check needs to move somewhere else? $grantType->validateTokenData() perhaps?

Add Logging with Monolog

We wanted to include logging with Monolog and add Symfony's HttpKernel as a dependency in composer.json for the project to set the NullLogger instance if none is given. The constructors would change to

public function __construct($storage = array(), array $config = array(), array $grantTypes = array(), array $responseTypes = array(), OAuth2_ResponseType_AccessTokenInterface $accessTokenResponseType = null, \Symfony\Component\HttpKernel\Log\LoggerInterface $logger = null)
{
    ...
    //set the logger
    $this->logger = $logger;
    if (!$this->logger instanceof \Symfony\Component\HttpKernel\Log\LoggerInterface) {
        $this->logger = new \Symfony\Component\HttpKernel\Log\NullLogger();
    }
}

You can then add you own implementation or Monolog and get logs from the server like this:

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

// create a log channel
$logger = new Logger('name');
$logger->pushHandler(new StreamHandler('path/to/your.log', Logger::DEBUG));

$server = new EasyBib\OAuth2\Server($app['oauth_storage'], $config, array(), array(), null, $logger);

An example can be found here: dazz/oauth2-server-php/feature/addLogging. This branch is now outdated so I would make a new branch from the develop branch to add it.

Before I add all my code again, I wanted to know if adding a dependency to HttpKernels NullLogger is ok an what do you think about this approach?
Having a logfile definitely helped us implement the client for testing the server.

Better support for unbounded scopes

The library currently assumes a small number of scopes, usually passed up front.
The Drupal integration stores scopes separately and has a requirement for supporting an unbounded (unlimited) number of scopes.
This makes getSupportedScopes() unsupportable.

The way I've accomplished this is by returning "*" from getSupportedScopes(), and then checking for that in checkScope() and doing a db query when needed.
See http://drupalcode.org/sandbox/bojanz/1928198.git/blob/refs/heads/7.x-2.x:/lib/Scope.php

However, that is a bit hacky, anyone calling getSupportedScopes() would be surprised by the results.
So, I was wondering if the library could support the unbounded use case better, by optimizing for it. (Since I'm unsure, no pull request yet).
Basically, it would mean removing the getSupportedScopes() method completely, and adding an additional checkScopes-like method (scopeExists() perhaps?) that would check the passed scope against the storage.

What do you think?

Duplicate lines in Server.php

Line 35 et 36
'user_credentials' => 'OAuth2_Storage_UserCredentialsInterface',
'user_credentials' => 'OAuth2_Storage_UserCredentialsInterface',

Inconsistent tests/interfaces, use of arrayHasKey in tests?

The specified array keys defined in the interface is inconsistent with the unit tests.
Example interface:
OAuth2_Storage_AuthorizationCodeInterface::getAuthorizationCode

/**
 * @return
 * An associative array as below, and NULL if the code is invalid:
 * - client_id: Stored client identifier.
 * - redirect_uri: Stored redirect URI.
 * - expires: Stored expiration in unix timestamp.
 * - scope: (optional) Stored scope values in space-separated string.
 */

Unit test:
OAuth2_Storage_PdoTest::testSetAuthorizationCode

$success = $storage->setAuthorizationCode('newcode', 'client ID', 'SOMEUSERID', 'http://adobe.com', time() + 20);
$this->assertTrue($success);

$code = $storage->getAuthorizationCode('newcode');
$this->assertNotNull($code);
$this->arrayHasKey('access_token', $code);
$this->arrayHasKey('client_id', $code);

The test above has several issues.

  • access_token should be authorization_code?
  • arrayHasKey returns PHPUnit_Framework_Constraint_ArrayHasKey, did you mean to call assertArrayHasKey?
    • Wouldn't it be better to assertEquals($code['authorization_code'], 'newcode'); instead?
      Minor:
  • Replace adobe.com with example.com?

I'd be willing to help out with these issues.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.