vendor/shopware/core/Framework/Api/OAuth/BearerTokenValidator.php line 42

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\Api\OAuth;
  3. use Doctrine\DBAL\Connection;
  4. use Lcobucci\JWT\Configuration;
  5. use Lcobucci\JWT\UnencryptedToken;
  6. use League\OAuth2\Server\AuthorizationValidators\AuthorizationValidatorInterface;
  7. use League\OAuth2\Server\Exception\OAuthServerException;
  8. use Psr\Http\Message\ServerRequestInterface;
  9. use Shopware\Core\Framework\Log\Package;
  10. use Shopware\Core\Framework\Uuid\Uuid;
  11. use Shopware\Core\PlatformRequest;
  12. #[Package('core')]
  13. class BearerTokenValidator implements AuthorizationValidatorInterface
  14. {
  15. private Connection $connection;
  16. private AuthorizationValidatorInterface $decorated;
  17. private Configuration $configuration;
  18. /**
  19. * @internal
  20. */
  21. public function __construct(
  22. AuthorizationValidatorInterface $decorated,
  23. Connection $connection,
  24. Configuration $configuration
  25. ) {
  26. $this->decorated = $decorated;
  27. $this->connection = $connection;
  28. $this->configuration = $configuration;
  29. }
  30. /**
  31. * @return ServerRequestInterface
  32. */
  33. public function validateAuthorization(ServerRequestInterface $request)
  34. {
  35. $request = $this->decorated->validateAuthorization($request);
  36. $header = $request->getHeader('authorization');
  37. $jwt = trim(preg_replace('/^(?:\s+)?Bearer\s/', '', $header[0]) ?? '');
  38. /** @var UnencryptedToken $token */
  39. $token = $this->configuration->parser()->parse($jwt);
  40. if ($userId = $request->getAttribute(PlatformRequest::ATTRIBUTE_OAUTH_USER_ID)) {
  41. $this->validateAccessTokenIssuedAt($token->claims()->get('iat', 0), $userId);
  42. }
  43. return $request;
  44. }
  45. /**
  46. * @throws OAuthServerException
  47. */
  48. private function validateAccessTokenIssuedAt(\DateTimeImmutable $tokenIssuedAt, string $userId): void
  49. {
  50. $lastUpdatedPasswordAt = $this->connection->createQueryBuilder()
  51. ->select(['last_updated_password_at'])
  52. ->from('user')
  53. ->where('id = :userId')
  54. ->setParameter('userId', Uuid::fromHexToBytes($userId))
  55. ->executeQuery()
  56. ->fetchOne();
  57. if ($lastUpdatedPasswordAt === false) {
  58. throw OAuthServerException::accessDenied('Access token is invalid');
  59. }
  60. if ($lastUpdatedPasswordAt === null) {
  61. return;
  62. }
  63. $lastUpdatedPasswordAt = strtotime($lastUpdatedPasswordAt);
  64. if ($tokenIssuedAt->getTimestamp() <= $lastUpdatedPasswordAt) {
  65. throw OAuthServerException::accessDenied('Access token is expired');
  66. }
  67. }
  68. }