Merge pull request #435 from juliangut/exception_middleware

V5 - Exception based access token check
This commit is contained in:
Alex Bilbie 2016-02-11 17:34:31 +00:00
commit 7a8c92b3d9
5 changed files with 34 additions and 20 deletions

View File

@ -243,9 +243,9 @@ class OAuthServerException extends \Exception
$response = $response->withHeader($header, $content);
}
$response = $response->withStatus($this->getHttpStatusCode());
$response->getBody()->write(json_encode($payload));
return $response;
return $response->withStatus($this->getHttpStatusCode());
}
/**

View File

@ -34,11 +34,13 @@ class AuthenticationServerMiddleware
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
{
try {
$response = $server->respondToRequest($request, $response);
$response = $this->server->respondToRequest($request, $response);
} catch (OAuthServerException $exception) {
return $exception->generateHttpResponse($response);
} catch (\Exception $exception) {
return $response->withStatus(500)->write($exception->getMessage());
$response->getBody()->write($exception->getMessage());
return $response->withStatus(500);
}
if (in_array($response->getStatusCode(), [400, 401, 500])) {

View File

@ -33,18 +33,14 @@ class ResourceServerMiddleware
*/
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
{
if ($request->hasHeader('authorization') === false) {
$exception = OAuthServerException::accessDenied('Missing authorization header');
try {
$request = $this->server->getResponseType()->determineAccessTokenInHeader($request);
} catch (OAuthServerException $exception) {
return $exception->generateHttpResponse($response);
}
} catch (\Exception $exception) {
$response->getBody()->write($exception->getMessage());
$request = $this->server->getResponseType()->determineAccessTokenInHeader($request);
if ($request->getAttribute('oauth_access_token') === null) {
$exception = OAuthServerException::accessDenied($request->getAttribute('oauth_access_token_error'));
return $exception->generateHttpResponse($response);
return $response->withStatus(500);
}
// Pass the request and response on to the next responder in the chain

View File

@ -13,7 +13,9 @@ namespace League\OAuth2\Server\ResponseTypes;
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
use Psr\Http\Message\ServerRequestInterface;
abstract class AbstractResponseType implements ResponseTypeInterface
{
@ -66,10 +68,22 @@ abstract class AbstractResponseType implements ResponseTypeInterface
}
/**
* @param \League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface $refreshToken
* {@inheritdoc}
*/
public function setRefreshToken(RefreshTokenEntityInterface $refreshToken)
{
$this->refreshToken = $refreshToken;
}
/**
* {@inheritdoc}
*/
public function determineAccessTokenInHeader(ServerRequestInterface $request)
{
if ($request->hasHeader('authorization') === false) {
throw OAuthServerException::accessDenied('Missing "Authorization" header');
}
return $request;
}
}

View File

@ -16,10 +16,10 @@ use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\Utils\KeyCrypt;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response;
class BearerTokenResponse extends AbstractResponseType
{
@ -78,6 +78,8 @@ class BearerTokenResponse extends AbstractResponseType
*/
public function determineAccessTokenInHeader(ServerRequestInterface $request)
{
$request = parent::determineAccessTokenInHeader($request);
$header = $request->getHeader('authorization');
$jwt = trim(preg_replace('/^(?:\s+)?Bearer\s/', '', $header[0]));
@ -85,12 +87,12 @@ class BearerTokenResponse extends AbstractResponseType
// Attempt to parse and validate the JWT
$token = (new Parser())->parse($jwt);
if ($token->verify(new Sha256(), $this->pathToPublicKey) === false) {
return $request->withAttribute('oauth_access_token_error', 'Access token could not be verified');
throw OAuthServerException::accessDenied('Access token could not be verified');
}
// Check if token has been revoked
if ($this->accessTokenRepository->isAccessTokenRevoked($token->getClaim('jti'))) {
return $request->withAttribute('oauth_access_token_error', 'Access token has been revoked');
throw OAuthServerException::accessDenied('Access token has been revoked');
}
// Return the request with additional attributes
@ -98,9 +100,9 @@ class BearerTokenResponse extends AbstractResponseType
->withAttribute('oauth_client_id', $token->getClaim('aud'))
->withAttribute('oauth_user_id', $token->getClaim('sub'))
->withAttribute('oauth_scopes', $token->getClaim('scopes'));
} catch (\InvalidArgumentException $e) {
} catch (\InvalidArgumentException $exception) {
// JWT couldn't be parsed so return the request as is
return $request->withAttribute('oauth_access_token_error', $e->getMessage());
throw OAuthServerException::accessDenied($exception->getMessage());
}
}
}