vendor/league/oauth2-server/src/AuthorizationValidators/BearerTokenValidator.php line 122

Open in your IDE?
  1. <?php
  2. /**
  3.  * @author      Alex Bilbie <hello@alexbilbie.com>
  4.  * @copyright   Copyright (c) Alex Bilbie
  5.  * @license     http://mit-license.org/
  6.  *
  7.  * @link        https://github.com/thephpleague/oauth2-server
  8.  */
  9. namespace League\OAuth2\Server\AuthorizationValidators;
  10. use DateTimeZone;
  11. use Lcobucci\Clock\SystemClock;
  12. use Lcobucci\JWT\Configuration;
  13. use Lcobucci\JWT\Signer\Key\InMemory;
  14. use Lcobucci\JWT\Signer\Rsa\Sha256;
  15. use Lcobucci\JWT\Validation\Constraint\LooseValidAt;
  16. use Lcobucci\JWT\Validation\Constraint\SignedWith;
  17. use Lcobucci\JWT\Validation\RequiredConstraintsViolated;
  18. use League\OAuth2\Server\CryptKey;
  19. use League\OAuth2\Server\CryptTrait;
  20. use League\OAuth2\Server\Exception\OAuthServerException;
  21. use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
  22. use Psr\Http\Message\ServerRequestInterface;
  23. class BearerTokenValidator implements AuthorizationValidatorInterface
  24. {
  25.     use CryptTrait;
  26.     /**
  27.      * @var AccessTokenRepositoryInterface
  28.      */
  29.     private $accessTokenRepository;
  30.     /**
  31.      * @var CryptKey
  32.      */
  33.     protected $publicKey;
  34.     /**
  35.      * @var Configuration
  36.      */
  37.     private $jwtConfiguration;
  38.     /**
  39.      * @var \DateInterval|null
  40.      */
  41.     private $jwtValidAtDateLeeway;
  42.     /**
  43.      * @param AccessTokenRepositoryInterface $accessTokenRepository
  44.      * @param \DateInterval|null             $jwtValidAtDateLeeway
  45.      */
  46.     public function __construct(AccessTokenRepositoryInterface $accessTokenRepository\DateInterval $jwtValidAtDateLeeway null)
  47.     {
  48.         $this->accessTokenRepository $accessTokenRepository;
  49.         $this->jwtValidAtDateLeeway $jwtValidAtDateLeeway;
  50.     }
  51.     /**
  52.      * Set the public key
  53.      *
  54.      * @param CryptKey $key
  55.      */
  56.     public function setPublicKey(CryptKey $key)
  57.     {
  58.         $this->publicKey $key;
  59.         $this->initJwtConfiguration();
  60.     }
  61.     /**
  62.      * Initialise the JWT configuration.
  63.      */
  64.     private function initJwtConfiguration()
  65.     {
  66.         $this->jwtConfiguration Configuration::forSymmetricSigner(
  67.             new Sha256(),
  68.             InMemory::plainText('empty''empty')
  69.         );
  70.         $clock = new SystemClock(new DateTimeZone(\date_default_timezone_get()));
  71.         $this->jwtConfiguration->setValidationConstraints(
  72.             new LooseValidAt($clock$this->jwtValidAtDateLeeway),
  73.             new SignedWith(
  74.                 new Sha256(),
  75.                 InMemory::plainText($this->publicKey->getKeyContents(), $this->publicKey->getPassPhrase() ?? '')
  76.             )
  77.         );
  78.     }
  79.     /**
  80.      * {@inheritdoc}
  81.      */
  82.     public function validateAuthorization(ServerRequestInterface $request)
  83.     {
  84.         if ($request->hasHeader('authorization') === false) {
  85.             throw OAuthServerException::accessDenied('Missing "Authorization" header');
  86.         }
  87.         $header $request->getHeader('authorization');
  88.         $jwt \trim((string) \preg_replace('/^\s*Bearer\s/'''$header[0]));
  89.         try {
  90.             // Attempt to parse the JWT
  91.             $token $this->jwtConfiguration->parser()->parse($jwt);
  92.         } catch (\Lcobucci\JWT\Exception $exception) {
  93.             throw OAuthServerException::accessDenied($exception->getMessage(), null$exception);
  94.         }
  95.         try {
  96.             // Attempt to validate the JWT
  97.             $constraints $this->jwtConfiguration->validationConstraints();
  98.             $this->jwtConfiguration->validator()->assert($token, ...$constraints);
  99.         } catch (RequiredConstraintsViolated $exception) {
  100.             throw OAuthServerException::accessDenied('Access token could not be verified'null$exception);
  101.         }
  102.         $claims $token->claims();
  103.         // Check if token has been revoked
  104.         if ($this->accessTokenRepository->isAccessTokenRevoked($claims->get('jti'))) {
  105.             throw OAuthServerException::accessDenied('Access token has been revoked');
  106.         }
  107.         // Return the request with additional attributes
  108.         return $request
  109.             ->withAttribute('oauth_access_token_id'$claims->get('jti'))
  110.             ->withAttribute('oauth_client_id'$this->convertSingleRecordAudToString($claims->get('aud')))
  111.             ->withAttribute('oauth_user_id'$claims->get('sub'))
  112.             ->withAttribute('oauth_scopes'$claims->get('scopes'));
  113.     }
  114.     /**
  115.      * Convert single record arrays into strings to ensure backwards compatibility between v4 and v3.x of lcobucci/jwt
  116.      *
  117.      * @param mixed $aud
  118.      *
  119.      * @return array|string
  120.      */
  121.     private function convertSingleRecordAudToString($aud)
  122.     {
  123.         return \is_array($aud) && \count($aud) === $aud[0] : $aud;
  124.     }
  125. }