mirror of
https://github.com/elyby/oauth2-server.git
synced 2025-05-31 14:12:07 +05:30
107 lines
3.6 KiB
PHP
107 lines
3.6 KiB
PHP
<?php
|
|
/**
|
|
* @author Alex Bilbie <hello@alexbilbie.com>
|
|
* @copyright Copyright (c) Alex Bilbie
|
|
* @license http://mit-license.org/
|
|
*
|
|
* @link https://github.com/thephpleague/oauth2-server
|
|
*/
|
|
|
|
namespace League\OAuth2\Server\AuthorizationValidators;
|
|
|
|
use BadMethodCallException;
|
|
use InvalidArgumentException;
|
|
use Lcobucci\JWT\Parser;
|
|
use Lcobucci\JWT\Signer\Rsa\Sha256;
|
|
use Lcobucci\JWT\ValidationData;
|
|
use League\OAuth2\Server\CryptKey;
|
|
use League\OAuth2\Server\CryptTrait;
|
|
use League\OAuth2\Server\Exception\OAuthServerException;
|
|
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
|
use Psr\Http\Message\ServerRequestInterface;
|
|
use RuntimeException;
|
|
|
|
class BearerTokenValidator implements AuthorizationValidatorInterface
|
|
{
|
|
use CryptTrait;
|
|
|
|
/**
|
|
* @var AccessTokenRepositoryInterface
|
|
*/
|
|
private $accessTokenRepository;
|
|
|
|
/**
|
|
* @var CryptKey
|
|
*/
|
|
protected $publicKey;
|
|
|
|
/**
|
|
* @param AccessTokenRepositoryInterface $accessTokenRepository
|
|
*/
|
|
public function __construct(AccessTokenRepositoryInterface $accessTokenRepository)
|
|
{
|
|
$this->accessTokenRepository = $accessTokenRepository;
|
|
}
|
|
|
|
/**
|
|
* Set the public key
|
|
*
|
|
* @param CryptKey $key
|
|
*/
|
|
public function setPublicKey(CryptKey $key)
|
|
{
|
|
$this->publicKey = $key;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function validateAuthorization(ServerRequestInterface $request)
|
|
{
|
|
if ($request->hasHeader('authorization') === false) {
|
|
throw OAuthServerException::accessDenied('Missing "Authorization" header');
|
|
}
|
|
|
|
$header = $request->getHeader('authorization');
|
|
$jwt = trim(preg_replace('/^(?:\s+)?Bearer\s/', '', $header[0]));
|
|
|
|
try {
|
|
// Attempt to parse and validate the JWT
|
|
$token = (new Parser())->parse($jwt);
|
|
try {
|
|
if ($token->verify(new Sha256(), $this->publicKey->getKeyPath()) === false) {
|
|
throw OAuthServerException::accessDenied('Access token could not be verified');
|
|
}
|
|
} catch (BadMethodCallException $exception) {
|
|
throw OAuthServerException::accessDenied('Access token is not signed', null, $exception);
|
|
}
|
|
|
|
// Ensure access token hasn't expired
|
|
$data = new ValidationData();
|
|
$data->setCurrentTime(time());
|
|
|
|
if ($token->validate($data) === false) {
|
|
throw OAuthServerException::accessDenied('Access token is invalid');
|
|
}
|
|
|
|
// Check if token has been revoked
|
|
if ($this->accessTokenRepository->isAccessTokenRevoked($token->getClaim('jti'))) {
|
|
throw OAuthServerException::accessDenied('Access token has been revoked');
|
|
}
|
|
|
|
// Return the request with additional attributes
|
|
return $request
|
|
->withAttribute('oauth_access_token_id', $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 $exception) {
|
|
// JWT couldn't be parsed so return the request as is
|
|
throw OAuthServerException::accessDenied($exception->getMessage(), null, $exception);
|
|
} catch (RuntimeException $exception) {
|
|
//JWR couldn't be parsed so return the request as is
|
|
throw OAuthServerException::accessDenied('Error while decoding to JSON', null, $exception);
|
|
}
|
|
}
|
|
}
|