src/EventListener/KeycloakRefreshTokenListener.php line 43

Open in your IDE?
  1. <?php
  2. namespace App\EventListener;
  3. use App\Security\Dto\TokensBag;
  4. use App\Service\KeycloakApiService;
  5. use Psr\Log\LoggerInterface;
  6. use RuntimeException;
  7. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  8. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  9. use Symfony\Component\HttpFoundation\RedirectResponse;
  10. use Symfony\Component\HttpKernel\Event\RequestEvent;
  11. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  12. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  13. use Symfony\Component\Security\Core\User\UserProviderInterface;
  14. use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface;
  15. class KeycloakRefreshTokenListener implements EventSubscriberInterface
  16. {
  17.     private LoggerInterface $logger;
  18.     private UserProviderInterface $userProvider;
  19.     private TokenStorageInterface $tokenStorage;
  20.     private UrlGeneratorInterface $urlGenerator;
  21.     private KeycloakApiService $keycloakApiService;
  22.     private ParameterBagInterface $param;
  23.     public function __construct(
  24.         LoggerInterface $logger,
  25.         UserProviderInterface $userProvider,
  26.         TokenStorageInterface $tokenStorage,
  27.         UrlGeneratorInterface $urlGenerator,
  28.         KeycloakApiService $keycloakApiService,
  29.         ParameterBagInterface $param,
  30.     ) {
  31.         $this->logger $logger;
  32.         $this->userProvider $userProvider;
  33.         $this->tokenStorage $tokenStorage;
  34.         $this->urlGenerator $urlGenerator;
  35.         $this->keycloakApiService $keycloakApiService;
  36.         $this->param $param;
  37.     }
  38.     public function onKernelRequest(RequestEvent $event): void
  39.     {
  40.         $request $event->getRequest();
  41.         $session $request->getSession();
  42.         $token $this->tokenStorage->getToken();
  43.         if (null === $token) {
  44.             return;
  45.         }
  46.         $tokens $token->getAttribute(TokensBag::class);
  47.         if (null === $tokens) {
  48.             throw new \LogicException(sprintf('%s token attribute is empty'TokensBag::class));
  49.         }
  50.         if (time() < $tokens->getJwtExpires()) {
  51.             return;
  52.         }
  53.         $refreshToken $session->get('oidc_refresh_token');
  54.         try {
  55.             $response $this->keycloakApiService->getTokenFromRefreshToken($refreshToken);
  56.         } catch (HttpExceptionInterface $e) {
  57.             $response $e->getResponse();
  58.             if (400 === $response->getStatusCode() && 'invalid_grant' === ($response->toArray(false)['error'] ?? null)) {
  59.                 // Logout when SSO session idle is reached
  60.                 $this->tokenStorage->setToken(null);
  61.                 $redirect $this->urlGenerator->generate('login');
  62.                 $event->setResponse(new RedirectResponse($redirect));
  63.                 return;
  64.             }
  65.             throw new RuntimeException(
  66.                 sprintf('Bad status code returned by openID server (%s)'$e->getResponse()->getStatusCode()),
  67.                 previous$e,
  68.             );
  69.         }
  70.         $responseData json_decode($responsetrue);
  71.         if (false === $responseData) {
  72.             throw new RuntimeException(sprintf('Can\'t parse json in response: %s'$response));
  73.         }
  74.         $jwtToken $responseData['id_token'] ?? null;
  75.         if (null === $jwtToken) {
  76.             throw new RuntimeException(sprintf('No access token found in response %s'$response));
  77.         }
  78.         $refreshToken $responseData['refresh_token'] ?? null;
  79.         if (null === $refreshToken) {
  80.             throw new RuntimeException(sprintf('No refresh token found in response %s'$response));
  81.         }
  82.         $this->logger->info(">>>>>>>>>>>>>>>>>> DEBUT REFRESH TOKEN >>>>>>>>>>>>>>>>>>");
  83.         $this->logger->debug($responseData['refresh_token']);
  84.         $this->logger->info("<<<<<<<<<<<<<<<<<< FIN REFRESH TOKEN <<<<<<<<<<<<<<<<<<");
  85.         $session->remove('oidc_access_token');
  86.         $session->remove('oidc_refresh_token');
  87.         $session->remove('oidc_expires_token');
  88.         $session->remove('oidc_expires_refresh_token');
  89.         $session->set('oidc_access_token'$responseData['access_token']);
  90.         $session->set('oidc_refresh_token'$responseData['refresh_token']);
  91.         $session->set('oidc_expires_token'$responseData['expires_in']);
  92.         $session->set('oidc_expires_refresh_token'$responseData['refresh_expires_in']);
  93.         setcookie("celaneo_access_token"""time() - 3600);
  94.         setcookie("celaneo_refresh_token"""time() - 3600);
  95.         setcookie("celaneo_access_token"$responseData['access_token'], time() + $responseData['expires_in']);
  96.         setcookie("celaneo_refresh_token"$responseData['refresh_token'], time() + $responseData['refresh_expires_in']);
  97.     }
  98.     public static function getSubscribedEvents(): array
  99.     {
  100.         return [RequestEvent::class => 'onKernelRequest'];
  101.     }
  102. }