<?php
namespace App\Security\Voter;
use App\Utils\KeycloakAdmin;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\User\UserInterface;
class IsActiveSessionVoter extends Voter
{
/**
* @param RequestStack $requestStack
* @param EventDispatcherInterface $dispatcher
* @param UrlGeneratorInterface $urlGenerator
*/
public function __construct(private readonly RequestStack $requestStack,
private readonly EventDispatcherInterface $dispatcher,
private readonly UrlGeneratorInterface $urlGenerator)
{
}
protected function supports(string $attribute, $subject): bool
{
return $attribute == 'IS_ACTIVE_SESSION';
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
// if the user is anonymous, do not grant access
if (!$user instanceof UserInterface) {
return false;
}
$credentials = $this->requestStack->getSession()->get('tokenSecurity');
if ($credentials) {
$keycloak = new KeycloakAdmin(false);
if ($keycloak->isSessionActive()) {
return true;
} else {
$this->dispatcher->addListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'));
}
}
return false;
}
private function onKernelResponse(ResponseEvent $event)
{
$event->setResponse(new RedirectResponse(
$this->urlGenerator->generate('app_logout')
));
}
}