src/Security/JWTAuthenticatedEventListener.php line 75

Open in your IDE?
  1. <?php
  2. namespace App\Security;
  3. use App\DataProvider\UserInfo\UserInfoItemDataProvider;
  4. use App\Model\Security\UserInfo;
  5. use App\Security\Exception\TokenNotWhitelistedException;
  6. use App\Service\Cache\CacheManager;
  7. use App\V4\Model\Security\UserInfo as UserInfoV4;
  8. use DateTime;
  9. use Exception;
  10. use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTAuthenticatedEvent;
  11. use Lexik\Bundle\JWTAuthenticationBundle\Security\Guard\JWTTokenAuthenticator;
  12. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
  13. /**
  14.  * Class JWTAuthenticatedEventListener.
  15.  */
  16. final class JWTAuthenticatedEventListener extends JWTTokenAuthenticator
  17. {
  18.     /**
  19.      * @var UserInfoItemDataProvider
  20.      */
  21.     private $userInfoItemDataProvider;
  22.     /**
  23.      * @var TokenStorage
  24.      */
  25.     private $tokenStorage;
  26.     /**
  27.      * @var CacheManager
  28.      */
  29.     private $cacheManager;
  30.     /**
  31.      * @var bool
  32.      */
  33.     private $enableTokenWhitelist;
  34.     /**
  35.      * @var string
  36.      */
  37.     private $environnement;
  38.     /**
  39.      * @param UserInfoItemDataProvider $userInfoItemDataProvider
  40.      * @param TokenStorage             $tokenStorage
  41.      * @param CacheManager             $cacheManager
  42.      * @param bool                     $enableTokenWhitelist
  43.      * @param string|null              $environnement
  44.      * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
  45.      */
  46.     public function __construct(
  47.         UserInfoItemDataProvider $userInfoItemDataProvider,
  48.         TokenStorage $tokenStorage,
  49.         CacheManager $cacheManager,
  50.         bool $enableTokenWhitelist false,
  51.         string $environnement null
  52.     ) {
  53.         $this->userInfoItemDataProvider $userInfoItemDataProvider;
  54.         $this->tokenStorage $tokenStorage;
  55.         $this->cacheManager $cacheManager;
  56.         $this->enableTokenWhitelist $enableTokenWhitelist;
  57.         $this->environnement $environnement;
  58.     }
  59.     /**
  60.      * @param JWTAuthenticatedEvent $event
  61.      *
  62.      * @return void
  63.      *
  64.      * @throws Exception
  65.      */
  66.     public function onLexikjwtauthenticationOnjwtauthenticated(JWTAuthenticatedEvent $event): void
  67.     {
  68.         $payload $event->getPayload();
  69.         $this->tokenStorage->setToken($event->getToken());
  70.         /**
  71.          * Voir : https://gist.github.com/benjaminrau/865f94d142605eb72a23a34ccdd0617a
  72.          * As a mechanism to invalidate issued tokes we force token issue date to be higher than a date stored on User::tokenValidAfter
  73.          * By updating the User::tokenValidAfter to current date all previously issued tokens become invalid.
  74.          *
  75.          * Its intended we dont mark as invalid if user isnt found on persistence level because we rely on core JWT
  76.          * implementation to handle this case. We want to handle only the validation of tokenValidAfter here.
  77.          *
  78.          * @var UserInfo User
  79.          */
  80.         // Toutes les 5 requêtes, on vérifie que le token de l'utilisateur n'est pas expiré
  81.         $current $this->cacheManager->get(UserInfo::class, 'jwtAuthCheck'$payload['user_id']);
  82.         if ($current 5) {
  83.             $current 0;
  84.             $user $this->userInfoItemDataProvider->getItem(UserInfo::class, $payload['user_id']);
  85.             if ($user &&
  86.                 $user->getTokenValidAfter() instanceof DateTime &&
  87.                 $payload['iat'] < $user->getTokenValidAfter()->getTimestamp() &&
  88.                 $this->enableTokenWhitelist
  89.             ) {
  90.                 throw new TokenNotWhitelistedException('This token is no longer authorized.');
  91.             }
  92.             $this->cacheManager->invalidate(UserInfo::class, CacheManager::CACHE_ACTION_KEY_ITEMnull$payload['user_id']);
  93.             $this->cacheManager->invalidate(UserInfoV4::class, CacheManager::CACHE_ACTION_KEY_ITEMnull$payload['user_id']);
  94.         }
  95.         $this->cacheManager->set(UserInfo::class, 'jwtAuthCheck'$current 1$payload['user_id']);
  96.         $this->cacheManager->set(UserInfoV4::class, 'jwtAuthCheck'$current 1$payload['user_id']);
  97.     }
  98. }