src/Platform/SecurityBundle/Service/Authenticator/JWTAuthenticator.php line 26

Open in your IDE?
  1. <?php
  2. namespace Platform\SecurityBundle\Service\Authenticator;
  3. use Cms\CoreBundle\Util\Doctrine\EntityManager;
  4. use Lexik\Bundle\JWTAuthenticationBundle\Exception\ExpiredTokenException;
  5. use Lexik\Bundle\JWTAuthenticationBundle\Exception\InvalidPayloadException;
  6. use Lexik\Bundle\JWTAuthenticationBundle\Exception\InvalidTokenException;
  7. use Lexik\Bundle\JWTAuthenticationBundle\Exception\JWTDecodeFailureException;
  8. use Lexik\Bundle\JWTAuthenticationBundle\Security\Authenticator\JWTAuthenticator as BaseJWTAuthenticator;
  9. use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
  10. use Lexik\Bundle\JWTAuthenticationBundle\TokenExtractor\ChainTokenExtractor;
  11. use Lexik\Bundle\JWTAuthenticationBundle\TokenExtractor\QueryParameterTokenExtractor;
  12. use Lexik\Bundle\JWTAuthenticationBundle\TokenExtractor\TokenExtractorInterface;
  13. use Platform\SecurityBundle\Doctrine\Identity\AccountRepository;
  14. use Platform\SecurityBundle\Entity\Identity\Account;
  15. use Platform\SecurityBundle\Service\AccountProvider;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
  18. use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
  19. use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
  20. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  21. use Symfony\Contracts\Translation\TranslatorInterface;
  22. use LogicException;
  23. class JWTAuthenticator extends BaseJWTAuthenticator
  24. {
  25.     /**
  26.      * @var EntityManager
  27.      */
  28.     protected EntityManager $entityManager;
  29.     /**
  30.      * @var JWTTokenManagerInterface
  31.      */
  32.     protected JWTTokenManagerInterface $jwtTokenManager;
  33.     /**
  34.      * @param EntityManager $entityManager
  35.      * @param JWTTokenManagerInterface $jwtManager
  36.      * @param EventDispatcherInterface $eventDispatcher
  37.      * @param TokenExtractorInterface $tokenExtractor
  38.      * @param AccountProvider $accountProvider
  39.      * @param TranslatorInterface $translator
  40.      */
  41.     public function __construct(
  42.         EntityManager $entityManager,
  43.         JWTTokenManagerInterface $jwtManager,
  44.         EventDispatcherInterface $eventDispatcher,
  45.         TokenExtractorInterface $tokenExtractor,
  46.         AccountProvider $accountProvider,
  47.         TranslatorInterface $translator
  48.     )
  49.     {
  50.         parent::__construct(
  51.             $jwtManager,
  52.             $eventDispatcher,
  53.             $tokenExtractor,
  54.             $accountProvider,
  55.             $translator
  56.         );
  57.         $this->entityManager $entityManager;
  58.         $this->jwtTokenManager $jwtManager;
  59.     }
  60.     /**
  61.      * @return TokenExtractorInterface
  62.      */
  63.     protected function getTokenExtractor(): TokenExtractorInterface
  64.     {
  65.         $chainExtractor parent::getTokenExtractor();
  66.         if ( ! $chainExtractor instanceof ChainTokenExtractor) {
  67.             throw new LogicException();
  68.         }
  69.         $chainExtractor->clearMap();
  70.         $chainExtractor->addExtractor(new QueryParameterTokenExtractor('token'));
  71.         return $chainExtractor;
  72.     }
  73.     /**
  74.      * @param Request $request
  75.      * @return Passport
  76.      */
  77.     public function doAuthenticate(Request $request): Passport
  78.     {
  79.         $token $this->getTokenExtractor()->extract($request);
  80.         if ($token === false) {
  81.             throw new LogicException('Unable to extract a JWT token from the request. Also, make sure to call `supports()` before `authenticate()` to get a proper client error.');
  82.         }
  83.         try {
  84.             if (!$payload $this->jwtTokenManager->parse($token)) {
  85.                 throw new InvalidTokenException('Invalid JWT Token');
  86.             }
  87.         } catch (JWTDecodeFailureException $e) {
  88.             if (JWTDecodeFailureException::EXPIRED_TOKEN === $e->getReason()) {
  89.                 throw new ExpiredTokenException();
  90.             }
  91.             throw new InvalidTokenException('Invalid JWT Token'0$e);
  92.         }
  93.         $uid $payload['id'] ?? null;
  94.         if (empty($uid)) {
  95.             throw new InvalidPayloadException('id');
  96.         }
  97.         $passport = new SelfValidatingPassport(
  98.             new UserBadge($uid, function ($identifier) {
  99.                 /** @var AccountRepository $accountRepository */
  100.                 $accountRepository $this->entityManager->getRepository(Account::class);
  101.                 return $accountRepository->findOneBy(['internalUid' => $identifier]);
  102.             })
  103.         );
  104.         $passport->setAttribute('payload', []);
  105.         $passport->setAttribute('token'$token);
  106.         return $passport;
  107.     }
  108. }