Files
oauth2-server/src/AuthorizationValidators/BearerTokenValidator.php
2018-11-13 12:28:39 +00:00

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);
}
}
}