mirror of
				https://github.com/elyby/oauth2-server.git
				synced 2025-05-31 14:12:07 +05:30 
			
		
		
		
	Merge pull request #435 from juliangut/exception_middleware
V5 - Exception based access token check
This commit is contained in:
		@@ -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());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -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])) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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');
 | 
			
		||||
 | 
			
		||||
            return $exception->generateHttpResponse($response);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            $request = $this->server->getResponseType()->determineAccessTokenInHeader($request);
 | 
			
		||||
 | 
			
		||||
        if ($request->getAttribute('oauth_access_token') === null) {
 | 
			
		||||
            $exception = OAuthServerException::accessDenied($request->getAttribute('oauth_access_token_error'));
 | 
			
		||||
 | 
			
		||||
        } catch (OAuthServerException $exception) {
 | 
			
		||||
            return $exception->generateHttpResponse($response);
 | 
			
		||||
        } catch (\Exception $exception) {
 | 
			
		||||
            $response->getBody()->write($exception->getMessage());
 | 
			
		||||
 | 
			
		||||
            return $response->withStatus(500);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Pass the request and response on to the next responder in the chain
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user