From f44b618531fc53b11fa2167ca2b08880188af390 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 12:57:50 +0000 Subject: [PATCH 01/28] Docblock tidy --- src/Exception/OAuthServerException.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Exception/OAuthServerException.php b/src/Exception/OAuthServerException.php index 982c8f73..f5630c63 100644 --- a/src/Exception/OAuthServerException.php +++ b/src/Exception/OAuthServerException.php @@ -202,7 +202,9 @@ class OAuthServerException extends \Exception /** * Generate a HTTP response * - * @return ResponseInterface + * @param \Psr\Http\Message\ResponseInterface $response + * + * @return \Psr\Http\Message\ResponseInterface */ public function generateHttpResponse(ResponseInterface $response = null) { From 7242a8db31cbc3e4a6a4724a47308f7c67b93e02 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 12:58:00 +0000 Subject: [PATCH 02/28] Added access denied exception --- src/Exception/OAuthServerException.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Exception/OAuthServerException.php b/src/Exception/OAuthServerException.php index f5630c63..701f1335 100644 --- a/src/Exception/OAuthServerException.php +++ b/src/Exception/OAuthServerException.php @@ -191,6 +191,18 @@ class OAuthServerException extends \Exception return new static('The refresh token is invalid.', 'invalid_request', 400, $hint); } + /** + * Access denied + * + * @param null|string $hint + * + * @return static + */ + public static function accessDenied($hint = null) + { + return new static('The resource owner or authorization server denied the request.', 401, $hint); + } + /** * @return string */ From 03391e963061907a3993720e9b679178284e1bee Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 12:58:15 +0000 Subject: [PATCH 03/28] Removed old access denied exception --- src/Exception/AccessDeniedException.php | 36 ------------------------- 1 file changed, 36 deletions(-) delete mode 100644 src/Exception/AccessDeniedException.php diff --git a/src/Exception/AccessDeniedException.php b/src/Exception/AccessDeniedException.php deleted file mode 100644 index e5d84b61..00000000 --- a/src/Exception/AccessDeniedException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Copyright (c) Alex Bilbie - * @license http://mit-license.org/ - * @link https://github.com/thephpleague/oauth2-server - */ - -namespace League\OAuth2\Server\Exception; - -/** - * Exception class - */ -class AccessDeniedException extends OAuthException -{ - /** - * {@inheritdoc} - */ - public $httpStatusCode = 401; - - /** - * {@inheritdoc} - */ - public $errorType = 'access_denied'; - - /** - * {@inheritdoc} - */ - public function __construct() - { - parent::__construct('The resource owner or authorization server denied the request.'); - } -} From 90d9d7bdd67eb13a2e8c89bcfdbbdec8873ab9c7 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 13:47:44 +0000 Subject: [PATCH 04/28] Required repositories are now set by the server --- src/Grant/AbstractGrant.php | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index ff7aaced..ed2404f2 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -69,20 +69,29 @@ abstract class AbstractGrant implements GrantTypeInterface protected $scopeRepository; /** - * @param \League\OAuth2\Server\Repositories\ClientRepositoryInterface $clientRepository - * @param \League\OAuth2\Server\Repositories\ScopeRepositoryInterface $scopeRepository - * @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository + * @param ClientRepositoryInterface $clientRepository */ - public function __construct( - ClientRepositoryInterface $clientRepository, - ScopeRepositoryInterface $scopeRepository, - AccessTokenRepositoryInterface $accessTokenRepository - ) { + public function setClientRepository(ClientRepositoryInterface $clientRepository) + { $this->clientRepository = $clientRepository; - $this->scopeRepository = $scopeRepository; + } + + /** + * @param AccessTokenRepositoryInterface $accessTokenRepository + */ + public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessTokenRepository) + { $this->accessTokenRepository = $accessTokenRepository; } + /** + * @param ScopeRepositoryInterface $scopeRepository + */ + public function setScopeRepository(ScopeRepositoryInterface $scopeRepository) + { + $this->scopeRepository = $scopeRepository; + } + /** * {@inheritdoc} */ From f74bca33abf58b337c2d5cb7103b4faf8abf1a09 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 13:48:40 +0000 Subject: [PATCH 05/28] Removed parameters that are no longer required --- src/Grant/PasswordGrant.php | 12 ------------ src/Grant/RefreshTokenGrant.php | 11 ----------- 2 files changed, 23 deletions(-) diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 30702744..2ebb5afe 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -12,13 +12,9 @@ namespace League\OAuth2\Server\Grant; use League\Event\Event; -use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface; use League\OAuth2\Server\Entities\Interfaces\UserEntityInterface; use League\OAuth2\Server\Exception\OAuthServerException; -use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; -use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface; -use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; use League\OAuth2\Server\Repositories\UserRepositoryInterface; use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface; use Psr\Http\Message\ServerRequestInterface; @@ -47,20 +43,12 @@ class PasswordGrant extends AbstractGrant /** * @param \League\OAuth2\Server\Repositories\UserRepositoryInterface $userRepository - * @param \League\OAuth2\Server\Repositories\ClientRepositoryInterface $clientRepository - * @param \League\OAuth2\Server\Repositories\ScopeRepositoryInterface $scopeRepository - * @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository * @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository */ public function __construct( UserRepositoryInterface $userRepository, - ClientRepositoryInterface $clientRepository, - ScopeRepositoryInterface $scopeRepository, - AccessTokenRepositoryInterface $accessTokenRepository, RefreshTokenRepositoryInterface $refreshTokenRepository ) { - parent::__construct($clientRepository, $scopeRepository, $accessTokenRepository); - $this->userRepository = $userRepository; $this->refreshTokenRepository = $refreshTokenRepository; } diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 4747811b..f9869b59 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -12,10 +12,7 @@ namespace League\OAuth2\Server\Grant; use League\OAuth2\Server\Exception\OAuthServerException; -use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; -use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface; -use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface; use League\OAuth2\Server\Utils\KeyCrypt; use Psr\Http\Message\ServerRequestInterface; @@ -45,20 +42,12 @@ class RefreshTokenGrant extends AbstractGrant /** * @param string $pathToPublicKey - * @param \League\OAuth2\Server\Repositories\ClientRepositoryInterface $clientRepository - * @param \League\OAuth2\Server\Repositories\ScopeRepositoryInterface $scopeRepository - * @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository * @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository */ public function __construct( $pathToPublicKey, - ClientRepositoryInterface $clientRepository, - ScopeRepositoryInterface $scopeRepository, - AccessTokenRepositoryInterface $accessTokenRepository, RefreshTokenRepositoryInterface $refreshTokenRepository ) { - parent::__construct($clientRepository, $scopeRepository, $accessTokenRepository); - $this->pathToPublicKey = $pathToPublicKey; $this->refreshTokenRepository = $refreshTokenRepository; } From e6cc6c35ecce1b3be416f97590b75ff3c7632efa Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 13:49:53 +0000 Subject: [PATCH 06/28] Scope delimiter string is now a constant --- src/Grant/AbstractGrant.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index ed2404f2..934456e6 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -29,6 +29,8 @@ use Psr\Http\Message\ServerRequestInterface; */ abstract class AbstractGrant implements GrantTypeInterface { + const SCOPE_DELIMITER_STRING = ' '; + /** * Grant identifier * @@ -181,7 +183,6 @@ abstract class AbstractGrant implements GrantTypeInterface /** * @param string $scopeParamValue A string containing a delimited set of scope identifiers - * @param string $scopeDelimiterString The delimiter between the scopes in the value string * @param ClientEntityInterface $client * @param string $redirectUri * @@ -190,12 +191,11 @@ abstract class AbstractGrant implements GrantTypeInterface */ public function validateScopes( $scopeParamValue, - $scopeDelimiterString, ClientEntityInterface $client, $redirectUri = null ) { $scopesList = array_filter( - explode($scopeDelimiterString, trim($scopeParamValue)), + explode(self::SCOPE_DELIMITER_STRING, trim($scopeParamValue)), function ($scope) { return !empty($scope); } From ad05a5cae6057fc503ce1abc03415dea1c344080 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 13:51:56 +0000 Subject: [PATCH 07/28] Scope delimiter is no longer a required parameter --- src/Grant/ClientCredentialsGrant.php | 5 ++--- src/Grant/GrantTypeInterface.php | 4 +--- src/Grant/PasswordGrant.php | 5 ++--- src/Grant/RefreshTokenGrant.php | 5 ++--- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/Grant/ClientCredentialsGrant.php b/src/Grant/ClientCredentialsGrant.php index 1ed22b8d..05f6a917 100644 --- a/src/Grant/ClientCredentialsGrant.php +++ b/src/Grant/ClientCredentialsGrant.php @@ -34,12 +34,11 @@ class ClientCredentialsGrant extends AbstractGrant public function respondToRequest( ServerRequestInterface $request, ResponseTypeInterface $responseType, - \DateInterval $tokenTTL, - $scopeDelimiter = ' ' + \DateInterval $tokenTTL ) { // Validate request $client = $this->validateClient($request); - $scopes = $this->validateScopes($this->getRequestParameter('scope', $request), $scopeDelimiter, $client); + $scopes = $this->validateScopes($this->getRequestParameter('scope', $request), $client); // Issue and persist access token $accessToken = $this->issueAccessToken($tokenTTL, $client, $client->getIdentifier(), $scopes); diff --git a/src/Grant/GrantTypeInterface.php b/src/Grant/GrantTypeInterface.php index fbaa88a1..3b775bfb 100644 --- a/src/Grant/GrantTypeInterface.php +++ b/src/Grant/GrantTypeInterface.php @@ -41,15 +41,13 @@ interface GrantTypeInterface * @param \Psr\Http\Message\ServerRequestInterface $request * @param \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType * @param \DateInterval $tokenTTL - * @param string $scopeDelimiter * * @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface */ public function respondToRequest( ServerRequestInterface $request, ResponseTypeInterface $responseType, - DateInterval $tokenTTL, - $scopeDelimiter = ' ' + DateInterval $tokenTTL ); /** diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 2ebb5afe..e526384d 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -59,13 +59,12 @@ class PasswordGrant extends AbstractGrant public function respondToRequest( ServerRequestInterface $request, ResponseTypeInterface $responseType, - \DateInterval $tokenTTL, - $scopeDelimiter = ' ' + \DateInterval $tokenTTL ) { // Validate request $client = $this->validateClient($request); $user = $this->validateUser($request); - $scopes = $this->validateScopes($this->getRequestParameter('scope', $request), $scopeDelimiter, $client); + $scopes = $this->validateScopes($this->getRequestParameter('scope', $request), $client); // Issue and persist new tokens $accessToken = $this->issueAccessToken($tokenTTL, $client, $user->getIdentifier(), $scopes); diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index f9869b59..21fe4f39 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -58,12 +58,11 @@ class RefreshTokenGrant extends AbstractGrant public function respondToRequest( ServerRequestInterface $request, ResponseTypeInterface $responseType, - \DateInterval $tokenTTL, - $scopeDelimiter = ' ' + \DateInterval $tokenTTL ) { $client = $this->validateClient($request); $oldRefreshToken = $this->validateOldRefreshToken($request, $client->getIdentifier()); - $scopes = $this->validateScopes($this->getRequestParameter('scope', $request), $scopeDelimiter, $client); + $scopes = $this->validateScopes($this->getRequestParameter('scope', $request), $client); // If no new scopes are requested then give the access token the original session scopes if (count($scopes) === 0) { From a4ce1e510ecbfd9042ca3ba11e2849c8c027cc99 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 13:53:18 +0000 Subject: [PATCH 08/28] Scope delimiter string is no longer configurable --- src/Server.php | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/Server.php b/src/Server.php index 1c46a0eb..535b7d21 100644 --- a/src/Server.php +++ b/src/Server.php @@ -113,26 +113,6 @@ class Server implements EmitterAwareInterface return $this->defaultAccessTokenTTL; } - /** - * Set the delimiter string used to separate scopes in a request - * - * @param string $scopeDelimiterString - */ - public function setScopeDelimiterString($scopeDelimiterString) - { - $this->scopeDelimiterString = $scopeDelimiterString; - } - - /** - * Get the delimiter string used to separate scopes in a request - * - * @return string - */ - protected function getScopeDelimiterString() - { - return $this->scopeDelimiterString; - } - /** * Enable a grant type on the server * @@ -188,8 +168,7 @@ class Server implements EmitterAwareInterface $tokenResponse = $grantType->respondToRequest( $request, $this->grantResponseTypes[$grantType->getIdentifier()], - $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()], - $this->getScopeDelimiterString() + $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] ); } } From e21a13c82c280f2989d4af89ca3e4c24f9db5b1c Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 13:54:39 +0000 Subject: [PATCH 09/28] Access token TTL is now configured on a per grant basis --- src/Server.php | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/src/Server.php b/src/Server.php index 535b7d21..ba4efd0d 100644 --- a/src/Server.php +++ b/src/Server.php @@ -43,15 +43,9 @@ class Server implements EmitterAwareInterface */ protected $defaultResponseType; - /** - * @var DateInterval - */ - protected $defaultAccessTokenTTL; - /** * @var string */ - protected $scopeDelimiterString = ' '; /** * New server instance @@ -90,29 +84,6 @@ class Server implements EmitterAwareInterface } /** - * Set the default TTL of access tokens - * - * @param DateInterval $defaultAccessTokenTTL - */ - public function setDefaultAccessTokenTTL(DateInterval $defaultAccessTokenTTL) - { - $this->defaultAccessTokenTTL = $defaultAccessTokenTTL; - } - - /** - * Get the default TTL of access tokens - * - * @return DateInterval - */ - protected function getDefaultAccessTokenTTL() - { - if (!$this->defaultAccessTokenTTL instanceof \DateInterval) { - $this->defaultAccessTokenTTL = new \DateInterval('PT01H'); // default token TTL of 1 hour - } - - return $this->defaultAccessTokenTTL; - } - /** * Enable a grant type on the server * @@ -123,7 +94,7 @@ class Server implements EmitterAwareInterface public function enableGrantType( GrantTypeInterface $grantType, ResponseTypeInterface $responseType = null, - \DateInterval $accessTokenTTL = null + \DateInterval $accessTokenTTL ) { $grantType->setEmitter($this->getEmitter()); $this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType; From 0cc13630ccf34276add87aa5f86143763aa404f8 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 13:54:55 +0000 Subject: [PATCH 10/28] Cody tidy --- src/Grant/ClientCredentialsGrant.php | 2 -- src/Grant/RefreshTokenGrant.php | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Grant/ClientCredentialsGrant.php b/src/Grant/ClientCredentialsGrant.php index 05f6a917..a52b9385 100644 --- a/src/Grant/ClientCredentialsGrant.php +++ b/src/Grant/ClientCredentialsGrant.php @@ -11,8 +11,6 @@ namespace League\OAuth2\Server\Grant; -use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface; -use League\OAuth2\Server\Exception\OAuthServerException; use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface; use Psr\Http\Message\ServerRequestInterface; diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 21fe4f39..b84c24c7 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -125,7 +125,7 @@ class RefreshTokenGrant extends AbstractGrant throw OAuthServerException::invalidRefreshToken( 'Token is not linked to client,' . ' got: ' . $clientId . - ' expected: '. $refreshTokenData['client_id'] + ' expected: ' . $refreshTokenData['client_id'] ); } From 645f719ee9be904e502d54e610bbc77b8e51aab7 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 13:55:12 +0000 Subject: [PATCH 11/28] Added new repository setter methods to GrantTypeInterface --- src/Grant/GrantTypeInterface.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/Grant/GrantTypeInterface.php b/src/Grant/GrantTypeInterface.php index 3b775bfb..4a474af5 100644 --- a/src/Grant/GrantTypeInterface.php +++ b/src/Grant/GrantTypeInterface.php @@ -13,6 +13,9 @@ namespace League\OAuth2\Server\Grant; use DateInterval; use League\Event\EmitterInterface; +use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; +use League\OAuth2\Server\Repositories\ClientRepositoryInterface; +use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface; use Psr\Http\Message\ServerRequestInterface; @@ -70,4 +73,26 @@ interface GrantTypeInterface * @param \League\Event\EmitterInterface $emitter */ public function setEmitter(EmitterInterface $emitter); + + /** + * Set the client repository + * + * @param \League\OAuth2\Server\Repositories\ClientRepositoryInterface $clientRepository + */ + public function setClientRepository(ClientRepositoryInterface $clientRepository); + + /** + * Set the access token repository + * + * @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository + */ + public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessTokenRepository); + + /** + * Set the scope repository + * + * @param \League\OAuth2\Server\Repositories\ScopeRepositoryInterface $scopeRepository + */ + public function setScopeRepository(ScopeRepositoryInterface $scopeRepository); + } From 8ee4dc7eb9550481ef9f0f9ec3a60f39f9d542dc Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 13:56:14 +0000 Subject: [PATCH 12/28] Fixed docblock --- src/ResponseTypes/ResponseTypeInterface.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ResponseTypes/ResponseTypeInterface.php b/src/ResponseTypes/ResponseTypeInterface.php index 00c3ed14..6524f049 100644 --- a/src/ResponseTypes/ResponseTypeInterface.php +++ b/src/ResponseTypes/ResponseTypeInterface.php @@ -29,11 +29,12 @@ interface ResponseTypeInterface public function setRefreshToken(RefreshTokenEntityInterface $refreshToken); /** - * Determine the access token in the authorization header + * Determine the access token in the authorization header and append OAUth properties to the request + * as attributes * * @param ServerRequestInterface $request * - * @return string + * @return ServerRequestInterface */ public function determineAccessTokenInHeader(ServerRequestInterface $request); From c7a904ca40ff22454598867f78d7cdce5de7dc1e Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 13:56:46 +0000 Subject: [PATCH 13/28] Added access token repository and public key path as required params to response type constructor --- src/ResponseTypes/AbstractResponseType.php | 24 +++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/ResponseTypes/AbstractResponseType.php b/src/ResponseTypes/AbstractResponseType.php index bed080fd..2388582f 100644 --- a/src/ResponseTypes/AbstractResponseType.php +++ b/src/ResponseTypes/AbstractResponseType.php @@ -13,6 +13,7 @@ namespace League\OAuth2\Server\ResponseTypes; use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface; use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface; +use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; abstract class AbstractResponseType implements ResponseTypeInterface { @@ -21,6 +22,11 @@ abstract class AbstractResponseType implements ResponseTypeInterface */ protected $pathToPrivateKey; + /** + * @var string + */ + protected $pathToPublicKey; + /** * @var \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface */ @@ -32,11 +38,23 @@ abstract class AbstractResponseType implements ResponseTypeInterface protected $refreshToken; /** - * @param string $pathToPrivateKey + * @var \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface */ - public function __construct($pathToPrivateKey) - { + protected $accessTokenRepository; + + /** + * @param string $pathToPrivateKey + * @param string $pathToPublicKey + * @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository + */ + public function __construct( + $pathToPrivateKey, + $pathToPublicKey, + AccessTokenRepositoryInterface $accessTokenRepository + ) { $this->pathToPrivateKey = $pathToPrivateKey; + $this->pathToPublicKey = $pathToPublicKey; + $this->accessTokenRepository = $accessTokenRepository; } /** From d755a8c01ddc5214f4c5964c4181aeafce60b7a8 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 13:57:07 +0000 Subject: [PATCH 14/28] Updated the validation to BearerTokenResponse --- src/ResponseTypes/BearerTokenResponse.php | 25 +++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/ResponseTypes/BearerTokenResponse.php b/src/ResponseTypes/BearerTokenResponse.php index 2397286e..d714b5b3 100644 --- a/src/ResponseTypes/BearerTokenResponse.php +++ b/src/ResponseTypes/BearerTokenResponse.php @@ -12,6 +12,7 @@ namespace League\OAuth2\Server\ResponseTypes; use Lcobucci\JWT\Builder; +use Lcobucci\JWT\Parser; use Lcobucci\JWT\Signer\Key; use Lcobucci\JWT\Signer\Rsa\Sha256; use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface; @@ -78,8 +79,28 @@ class BearerTokenResponse extends AbstractResponseType public function determineAccessTokenInHeader(ServerRequestInterface $request) { $header = $request->getHeader('authorization'); - $accessToken = trim(preg_replace('/^(?:\s+)?Bearer\s/', '', $header)); + $jwt = trim(preg_replace('/^(?:\s+)?Bearer\s/', '', $header)); - return ($accessToken === 'Bearer') ? '' : $accessToken; + try { + // Attempt to parse and validate the JWT + $token = (new Parser())->parse($jwt); + if ($token->verify(new Sha256(), $this->pathToPublicKey) === false) { + return $request; + } + + // Check if token has been revoked + if ($this->accessTokenRepository->isAccessTokenRevoked($token->getClaim('jwt'))) { + return $request; + } + + // Return the request with additional attributes + return $request->withAttribute('oauth_access_token', $token->getClaim('jti')) + ->withAttribute('oauth_client_id', $token->getClaim('aud')) + ->withAttribute('oauth_user_id', $token->getClaim('sub')) + ->withAttribute('oauth_scopes', $token->getClaim('scopes')); + } catch (\InvalidArgumentException $e) { + // JWT couldn't be parsed so return the request as is + return $request; + } } } From e43d95415bd8b69934df7c269b76468cc66c473b Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 14:03:07 +0000 Subject: [PATCH 15/28] Inject required params into grant type --- src/Server.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Server.php b/src/Server.php index ba4efd0d..f0df7d61 100644 --- a/src/Server.php +++ b/src/Server.php @@ -77,7 +77,11 @@ class Server implements EmitterAwareInterface protected function getDefaultResponseType() { if (!$this->defaultResponseType instanceof ResponseTypeInterface) { - $this->defaultResponseType = new BearerTokenResponse($this->defaultPrivateKeyPath); + $this->defaultResponseType = new BearerTokenResponse( + $this->defaultPrivateKeyPath, + $this->defaultPublicKeyPath, + $this->accessTokenRepository + ); } return $this->defaultResponseType; @@ -96,6 +100,10 @@ class Server implements EmitterAwareInterface ResponseTypeInterface $responseType = null, \DateInterval $accessTokenTTL ) { + $grantType->setAccessTokenRepository($this->accessTokenRepository); + $grantType->setClientRepository($this->clientRepository); + $grantType->setScopeRepository($this->scopeRepository); + $grantType->setEmitter($this->getEmitter()); $this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType; From 6332ecfa0b7b9ce1147768802ebb5306d4899aa0 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 14:03:33 +0000 Subject: [PATCH 16/28] Removed default overrides --- src/Server.php | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/Server.php b/src/Server.php index f0df7d61..b9d67e24 100644 --- a/src/Server.php +++ b/src/Server.php @@ -87,17 +87,14 @@ class Server implements EmitterAwareInterface return $this->defaultResponseType; } - /** /** * Enable a grant type on the server * * @param \League\OAuth2\Server\Grant\GrantTypeInterface $grantType - * @param ResponseTypeInterface $responseType * @param DateInterval $accessTokenTTL */ public function enableGrantType( GrantTypeInterface $grantType, - ResponseTypeInterface $responseType = null, \DateInterval $accessTokenTTL ) { $grantType->setAccessTokenRepository($this->accessTokenRepository); @@ -108,18 +105,10 @@ class Server implements EmitterAwareInterface $this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType; // Set grant response type - if ($responseType instanceof ResponseTypeInterface) { - $this->grantResponseTypes[$grantType->getIdentifier()] = $responseType; - } else { - $this->grantResponseTypes[$grantType->getIdentifier()] = $this->getDefaultResponseType(); - } + $this->grantResponseTypes[$grantType->getIdentifier()] = $this->getDefaultResponseType(); // Set grant access token TTL - if ($accessTokenTTL instanceof \DateInterval) { - $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] = $accessTokenTTL; - } else { - $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] = $this->getDefaultAccessTokenTTL(); - } + $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] = $accessTokenTTL; } /** From cd68103267ceb84dcffbbf7277a40319f86b6495 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 14:03:41 +0000 Subject: [PATCH 17/28] New server constructor --- src/Server.php | 53 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/src/Server.php b/src/Server.php index b9d67e24..dfb61303 100644 --- a/src/Server.php +++ b/src/Server.php @@ -7,6 +7,9 @@ use League\Event\EmitterAwareInterface; use League\Event\EmitterAwareTrait; use League\OAuth2\Server\Exception\OAuthServerException; use League\OAuth2\Server\Grant\GrantTypeInterface; +use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; +use League\OAuth2\Server\Repositories\ClientRepositoryInterface; +use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; use League\OAuth2\Server\ResponseTypes\BearerTokenResponse; use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface; use Psr\Http\Message\ResponseInterface; @@ -46,27 +49,47 @@ class Server implements EmitterAwareInterface /** * @var string */ + private $defaultPublicKeyPath; + + /** + * @var \League\OAuth2\Server\Repositories\ClientRepositoryInterface + */ + private $clientRepository; + + /** + * @var \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface + */ + private $accessTokenRepository; + + /** + * @var \League\OAuth2\Server\Repositories\ScopeRepositoryInterface + */ + private $scopeRepository; /** * New server instance * - * @param string $defaultPrivateKeyPath - * @param DateInterval $defaultAccessTokenTTL + * @param \League\OAuth2\Server\Repositories\ClientRepositoryInterface $clientRepository + * @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository + * @param \League\OAuth2\Server\Repositories\ScopeRepositoryInterface $scopeRepository + * @param string $defaultPrivateKeyPath + * @param string $defaultPublicKeyPath + * @param null|\League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType */ - public function __construct($defaultPrivateKeyPath, \DateInterval $defaultAccessTokenTTL = null) - { + public function __construct( + ClientRepositoryInterface $clientRepository, + AccessTokenRepositoryInterface $accessTokenRepository, + ScopeRepositoryInterface $scopeRepository, + $defaultPrivateKeyPath, + $defaultPublicKeyPath, + ResponseTypeInterface $responseType = null + ) { $this->defaultPrivateKeyPath = $defaultPrivateKeyPath; - $this->defaultAccessTokenTTL = $defaultAccessTokenTTL; - } - - /** - * Set the default token type that grants will return - * - * @param ResponseTypeInterface $defaultTokenType - */ - public function setDefaultResponseType(ResponseTypeInterface $defaultTokenType) - { - $this->defaultResponseType = $defaultTokenType; + $this->defaultPublicKeyPath = $defaultPublicKeyPath; + $this->clientRepository = $clientRepository; + $this->accessTokenRepository = $accessTokenRepository; + $this->scopeRepository = $scopeRepository; + $this->defaultResponseType = $responseType; } /** From 6c787c374ca82438dc4ecc13155b0b8faca1c3b5 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 14:08:42 +0000 Subject: [PATCH 18/28] First commit of ResourceServerMiddleware --- src/Middleware/ResourceServerMiddleware.php | 54 +++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/Middleware/ResourceServerMiddleware.php diff --git a/src/Middleware/ResourceServerMiddleware.php b/src/Middleware/ResourceServerMiddleware.php new file mode 100644 index 00000000..b1f26bf2 --- /dev/null +++ b/src/Middleware/ResourceServerMiddleware.php @@ -0,0 +1,54 @@ +server = $server; + } + + /** + * @param \Psr\Http\Message\ServerRequestInterface $request + * @param \Psr\Http\Message\ResponseInterface $response + * @param callable $next + * + * @return \Psr\Http\Message\ResponseInterface + */ + public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next) + { + if ($request->hasHeader('authorization') === false) { + $exception = OAuthServerException::accessDenied('Missing authorization header'); + + return $exception->generateHttpResponse($response); + } + + $request = $this->server->getDefaultResponseType()->determineAccessTokenInHeader($request); + + if ($request->getAttribute('oauth_access_token') === null) { + $exception = OAuthServerException::accessDenied('Access token was invalid'); + + return $exception->generateHttpResponse($response); + } + + // Pass the request and response on to the next responder in the chain + return $next($request, $response); + } +} From 19b12cda8e1d7e8372436e044fba5cab57bf7012 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 14:08:53 +0000 Subject: [PATCH 19/28] Made getDefaultResponseType public --- src/Server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server.php b/src/Server.php index dfb61303..9c8e21e7 100644 --- a/src/Server.php +++ b/src/Server.php @@ -97,7 +97,7 @@ class Server implements EmitterAwareInterface * * @return ResponseTypeInterface */ - protected function getDefaultResponseType() + public function getDefaultResponseType() { if (!$this->defaultResponseType instanceof ResponseTypeInterface) { $this->defaultResponseType = new BearerTokenResponse( From 5f22ead2871ae7f1d9051f5f52384e09d6c2a7bf Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 14:11:21 +0000 Subject: [PATCH 20/28] Updated access denied hint --- src/Exception/OAuthServerException.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Exception/OAuthServerException.php b/src/Exception/OAuthServerException.php index 701f1335..c7a04b9c 100644 --- a/src/Exception/OAuthServerException.php +++ b/src/Exception/OAuthServerException.php @@ -200,7 +200,7 @@ class OAuthServerException extends \Exception */ public static function accessDenied($hint = null) { - return new static('The resource owner or authorization server denied the request.', 401, $hint); + return new static('The server denied the request.', 401, $hint); } /** From f6664c69178a67f011b996c42a68364948c3c7c2 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 14:21:35 +0000 Subject: [PATCH 21/28] Private and public key paths are injected into grants now --- src/Grant/AbstractGrant.php | 26 ++++++++++++++++++++++++++ src/Grant/GrantTypeInterface.php | 13 +++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 934456e6..74af64b9 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -70,6 +70,16 @@ abstract class AbstractGrant implements GrantTypeInterface */ protected $scopeRepository; + /** + * @var string + */ + protected $pathToPrivateKey; + + /** + * @var string + */ + protected $pathToPublicKey; + /** * @param ClientRepositoryInterface $clientRepository */ @@ -94,6 +104,22 @@ abstract class AbstractGrant implements GrantTypeInterface $this->scopeRepository = $scopeRepository; } + /** + * @param string $pathToPrivateKey + */ + public function setPathToPrivateKey($pathToPrivateKey) + { + $this->pathToPrivateKey = $pathToPrivateKey; + } + + /** + * @param string $pathToPublicKey + */ + public function setPathToPublicKey($pathToPublicKey) + { + $this->pathToPublicKey = $pathToPublicKey; + } + /** * {@inheritdoc} */ diff --git a/src/Grant/GrantTypeInterface.php b/src/Grant/GrantTypeInterface.php index 4a474af5..5bc9bf08 100644 --- a/src/Grant/GrantTypeInterface.php +++ b/src/Grant/GrantTypeInterface.php @@ -95,4 +95,17 @@ interface GrantTypeInterface */ public function setScopeRepository(ScopeRepositoryInterface $scopeRepository); + /** + * Set the path to the private key + * + * @param string $pathToPrivateKey + */ + public function setPathToPrivateKey($pathToPrivateKey); + + /** + * Set the path to the public key + * + * @param string $pathToPublicKey + */ + public function setPathToPublicKey($pathToPublicKey); } From 5a8659471c5eb1b681694494aca48283326eb961 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 14:21:53 +0000 Subject: [PATCH 22/28] Public key is set in abstract grant now --- src/Grant/RefreshTokenGrant.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index b84c24c7..99e32401 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -30,25 +30,17 @@ class RefreshTokenGrant extends AbstractGrant */ protected $identifier = 'refresh_token'; - /** - * @var string - */ - private $pathToPublicKey; - /** * @var \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface */ private $refreshTokenRepository; /** - * @param string $pathToPublicKey * @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository */ public function __construct( - $pathToPublicKey, RefreshTokenRepositoryInterface $refreshTokenRepository ) { - $this->pathToPublicKey = $pathToPublicKey; $this->refreshTokenRepository = $refreshTokenRepository; } From 0486d93fa342949841297fc885c3c5d1d202f5aa Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 14:23:02 +0000 Subject: [PATCH 23/28] Removed default wording as there are no overrides --- src/Server.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Server.php b/src/Server.php index 9c8e21e7..c2d90037 100644 --- a/src/Server.php +++ b/src/Server.php @@ -39,7 +39,7 @@ class Server implements EmitterAwareInterface /** * @var string */ - protected $defaultPrivateKeyPath; + protected $privateKeyPath; /** * @var ResponseTypeInterface @@ -49,7 +49,7 @@ class Server implements EmitterAwareInterface /** * @var string */ - private $defaultPublicKeyPath; + private $publicKeyPath; /** * @var \League\OAuth2\Server\Repositories\ClientRepositoryInterface @@ -72,24 +72,24 @@ class Server implements EmitterAwareInterface * @param \League\OAuth2\Server\Repositories\ClientRepositoryInterface $clientRepository * @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository * @param \League\OAuth2\Server\Repositories\ScopeRepositoryInterface $scopeRepository - * @param string $defaultPrivateKeyPath - * @param string $defaultPublicKeyPath + * @param string $privateKeyPath + * @param string $publicKeyPath * @param null|\League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType */ public function __construct( ClientRepositoryInterface $clientRepository, AccessTokenRepositoryInterface $accessTokenRepository, ScopeRepositoryInterface $scopeRepository, - $defaultPrivateKeyPath, - $defaultPublicKeyPath, + $privateKeyPath, + $publicKeyPath, ResponseTypeInterface $responseType = null ) { - $this->defaultPrivateKeyPath = $defaultPrivateKeyPath; - $this->defaultPublicKeyPath = $defaultPublicKeyPath; $this->clientRepository = $clientRepository; $this->accessTokenRepository = $accessTokenRepository; $this->scopeRepository = $scopeRepository; $this->defaultResponseType = $responseType; + $this->privateKeyPath = $privateKeyPath; + $this->publicKeyPath = $publicKeyPath; } /** @@ -123,6 +123,8 @@ class Server implements EmitterAwareInterface $grantType->setAccessTokenRepository($this->accessTokenRepository); $grantType->setClientRepository($this->clientRepository); $grantType->setScopeRepository($this->scopeRepository); + $grantType->setPathToPrivateKey($this->privateKeyPath); + $grantType->setPathToPublicKey($this->publicKeyPath); $grantType->setEmitter($this->getEmitter()); $this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType; From 3d08051cbbc5186aa20eae3c2a81fbbd97dce9ec Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 14:23:18 +0000 Subject: [PATCH 24/28] Removed default wording as there is no override --- src/Middleware/ResourceServerMiddleware.php | 2 +- src/Server.php | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Middleware/ResourceServerMiddleware.php b/src/Middleware/ResourceServerMiddleware.php index b1f26bf2..70711b94 100644 --- a/src/Middleware/ResourceServerMiddleware.php +++ b/src/Middleware/ResourceServerMiddleware.php @@ -40,7 +40,7 @@ class ResourceServerMiddleware return $exception->generateHttpResponse($response); } - $request = $this->server->getDefaultResponseType()->determineAccessTokenInHeader($request); + $request = $this->server->getResponseType()->determineAccessTokenInHeader($request); if ($request->getAttribute('oauth_access_token') === null) { $exception = OAuthServerException::accessDenied('Access token was invalid'); diff --git a/src/Server.php b/src/Server.php index c2d90037..034173cc 100644 --- a/src/Server.php +++ b/src/Server.php @@ -44,7 +44,7 @@ class Server implements EmitterAwareInterface /** * @var ResponseTypeInterface */ - protected $defaultResponseType; + protected $responseType; /** * @var string @@ -87,27 +87,27 @@ class Server implements EmitterAwareInterface $this->clientRepository = $clientRepository; $this->accessTokenRepository = $accessTokenRepository; $this->scopeRepository = $scopeRepository; - $this->defaultResponseType = $responseType; $this->privateKeyPath = $privateKeyPath; $this->publicKeyPath = $publicKeyPath; + $this->responseType = $responseType; } /** - * Get the default token type that grants will return + * Get the token type that grants will return in the HTTP response * * @return ResponseTypeInterface */ - public function getDefaultResponseType() + public function getResponseType() { - if (!$this->defaultResponseType instanceof ResponseTypeInterface) { - $this->defaultResponseType = new BearerTokenResponse( - $this->defaultPrivateKeyPath, - $this->defaultPublicKeyPath, + if (!$this->responseType instanceof ResponseTypeInterface) { + $this->responseType = new BearerTokenResponse( + $this->privateKeyPath, + $this->publicKeyPath, $this->accessTokenRepository ); } - return $this->defaultResponseType; + return $this->responseType; } /** @@ -130,7 +130,7 @@ class Server implements EmitterAwareInterface $this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType; // Set grant response type - $this->grantResponseTypes[$grantType->getIdentifier()] = $this->getDefaultResponseType(); + $this->grantResponseTypes[$grantType->getIdentifier()] = $this->getResponseType(); // Set grant access token TTL $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] = $accessTokenTTL; From 168e7640c6e8217b7e961151de522810b3edce6e Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 14:23:42 +0000 Subject: [PATCH 25/28] Updated examples to use new API --- examples/public/client_credentials.php | 38 +++++++++++++------ examples/public/password.php | 52 +++++++++++++++----------- 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/examples/public/client_credentials.php b/examples/public/client_credentials.php index 1e671d3a..684e3003 100644 --- a/examples/public/client_credentials.php +++ b/examples/public/client_credentials.php @@ -14,19 +14,33 @@ use Slim\Http\Response; include(__DIR__ . '/../vendor/autoload.php'); -// Setup the authorization server -$server = new Server('file://' . __DIR__ . '/../private.key'); - -// Init our repositories -$clientRepository = new ClientRepository(); -$scopeRepository = new ScopeRepository(); -$accessTokenRepository = new AccessTokenRepository(); - -// Enable the client credentials grant on the server -$server->enableGrantType(new ClientCredentialsGrant($clientRepository, $scopeRepository, $accessTokenRepository)); - // App -$app = new App([Server::class => $server]); +$app = new App([ + Server::class => function () { + + // Init our repositories + $clientRepository = new ClientRepository(); + $scopeRepository = new ScopeRepository(); + $accessTokenRepository = new AccessTokenRepository(); + + $privateKeyPath = 'file://' . __DIR__ . '/../private.key'; + $publicKeyPath = 'file://' . __DIR__ . '/../public.key'; + + // Setup the authorization server + $server = new Server( + $clientRepository, + $accessTokenRepository, + $scopeRepository, + $privateKeyPath, + $publicKeyPath + ); + + // Enable the client credentials grant on the server with a token TTL of 1 hour + $server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1H')); + + return $server; + } +]); $app->post('/access_token', function (Request $request, Response $response) { /** @var Server $server */ diff --git a/examples/public/password.php b/examples/public/password.php index de73d63d..1be26880 100644 --- a/examples/public/password.php +++ b/examples/public/password.php @@ -16,28 +16,38 @@ use Slim\Http\Response; include(__DIR__ . '/../vendor/autoload.php'); -// Setup the authorization server -$server = new Server('file://' . __DIR__ . '/../private.key'); - -// Init our repositories -$userRepository = new UserRepository(); -$clientRepository = new ClientRepository(); -$scopeRepository = new ScopeRepository(); -$accessTokenRepository = new AccessTokenRepository(); -$refreshTokenRepository = new RefreshTokenRepository(); - -// Enable the client credentials grant on the server -$passwordGrant = new PasswordGrant( - $userRepository, - $clientRepository, - $scopeRepository, - $accessTokenRepository, - $refreshTokenRepository -); -$server->enableGrantType($passwordGrant); - // App -$app = new App([Server::class => $server]); +$app = new App([ + Server::class => function () { + + // Init our repositories + $clientRepository = new ClientRepository(); + $scopeRepository = new ScopeRepository(); + $accessTokenRepository = new AccessTokenRepository(); + $userRepository = new UserRepository(); + $refreshTokenRepository = new RefreshTokenRepository(); + + $privateKeyPath = 'file://' . __DIR__ . '/../private.key'; + $publicKeyPath = 'file://' . __DIR__ . '/../public.key'; + + // Setup the authorization server + $server = new Server( + $clientRepository, + $accessTokenRepository, + $scopeRepository, + $privateKeyPath, + $publicKeyPath + ); + + // Enable the client credentials grant on the server with a token TTL of 1 hour + $server->enableGrantType( + new PasswordGrant($userRepository, $refreshTokenRepository), + new \DateInterval('PT1H') + ); + + return $server; + } +]); $app->post('/access_token', function (Request $request, Response $response) { /** @var Server $server */ From 3c4347e3859f201ba33272bbaf8de135a6ccf28a Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 14:25:44 +0000 Subject: [PATCH 26/28] Updated refresh token example --- examples/public/refresh_token.php | 44 +++++++++++++++++-------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/examples/public/refresh_token.php b/examples/public/refresh_token.php index d41e940b..ad9bf0cb 100644 --- a/examples/public/refresh_token.php +++ b/examples/public/refresh_token.php @@ -8,7 +8,6 @@ use OAuth2ServerExamples\Repositories\AccessTokenRepository; use OAuth2ServerExamples\Repositories\ClientRepository; use OAuth2ServerExamples\Repositories\RefreshTokenRepository; use OAuth2ServerExamples\Repositories\ScopeRepository; -use OAuth2ServerExamples\Repositories\UserRepository; use Slim\App; use Slim\Http\Request; @@ -16,28 +15,33 @@ use Slim\Http\Response; include(__DIR__ . '/../vendor/autoload.php'); -// Setup the authorization server -$server = new Server('file://' . __DIR__ . '/../private.key'); -// Init our repositories -$userRepository = new UserRepository(); -$clientRepository = new ClientRepository(); -$scopeRepository = new ScopeRepository(); -$accessTokenRepository = new AccessTokenRepository(); -$refreshTokenRepository = new RefreshTokenRepository(); - -// Enable the client credentials grant on the server -$refreshTokenGrant = new RefreshTokenGrant( - 'file://' . __DIR__ . '/../public.key', - $clientRepository, - $scopeRepository, - $accessTokenRepository, - $refreshTokenRepository -); -$server->enableGrantType($refreshTokenGrant); // App -$app = new App([Server::class => $server]); +$app = new App([Server::class => function () { + // Init our repositories + $clientRepository = new ClientRepository(); + $scopeRepository = new ScopeRepository(); + $accessTokenRepository = new AccessTokenRepository(); + $refreshTokenRepository = new RefreshTokenRepository(); + + $privateKeyPath = 'file://' . __DIR__ . '/../private.key'; + $publicKeyPath = 'file://' . __DIR__ . '/../public.key'; + + // Setup the authorization server + $server = new Server( + $clientRepository, + $accessTokenRepository, + $scopeRepository, + $privateKeyPath, + $publicKeyPath + ); + + // Enable the refresh token grant on the server + $server->enableGrantType(new RefreshTokenGrant($refreshTokenRepository), new \DateInterval('PT1H')); + + return $server; +}]); $app->post('/access_token', function (Request $request, Response $response) { /** @var Server $server */ From 06ee612bb1c5a664ab8e546057a78d6841c00d4c Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 14:25:54 +0000 Subject: [PATCH 27/28] Updated composer.lock in example --- examples/composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/composer.lock b/examples/composer.lock index 466319f3..251ab498 100644 --- a/examples/composer.lock +++ b/examples/composer.lock @@ -148,7 +148,7 @@ "dist": { "type": "path", "url": "../", - "reference": "dce1620f60d9f1a44a9ec99b6168810a8030c20c", + "reference": "168e7640c6e8217b7e961151de522810b3edce6e", "shasum": null }, "require": { From 660378c7b35e03a7c0b82394fd7d333f1e9eb23d Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 17 Jan 2016 14:28:13 +0000 Subject: [PATCH 28/28] Added MAC auth scheme to 401 header --- src/Exception/OAuthServerException.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Exception/OAuthServerException.php b/src/Exception/OAuthServerException.php index c7a04b9c..baf16f50 100644 --- a/src/Exception/OAuthServerException.php +++ b/src/Exception/OAuthServerException.php @@ -280,6 +280,8 @@ class OAuthServerException extends \Exception if ($authHeader !== []) { if (strpos($authHeader[0], 'Bearer') === 0) { $authScheme = 'Bearer'; + } elseif (strpos($authHeader[0], 'MAC') === 0) { + $authScheme = 'MAC'; } elseif (strpos($authHeader[0], 'Basic') === 0) { $authScheme = 'Basic'; }