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

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