<?php
namespace App\EventListener;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
class AccessDeniedListener implements EventSubscriberInterface
{
/**
* @var TokenStorageInterface
*/
private $tokenStorage;
/**
* @var LoggerInterface
*/
private $logger;
/**
* @param TokenStorageInterface $tokenStorage
* @param LoggerInterface $logger
*/
public function __construct(TokenStorageInterface $tokenStorage, LoggerInterface $logger)
{
$this->tokenStorage = $tokenStorage;
$this->logger = $logger;
}
/**
* @return array[]
*/
public static function getSubscribedEvents(): array
{
return [
// the priority must be greater than the Security HTTP
// ExceptionListener, to make sure it's called before
// the default exception listener
KernelEvents::EXCEPTION => ['onKernelException', 2],
];
}
/**
* @param ExceptionEvent $event
*/
public function onKernelException(ExceptionEvent $event): void
{
$exception = $event->getThrowable();
if (!$exception instanceof AccessDeniedException) {
return;
}
$token = $this->tokenStorage->getToken();
$user = is_null($token) ? null : $token->getUser();
$userIdentifier = is_null($user) ? '' : $user->getUserIdentifier();
$roles = is_null($token) ? [] : $token->getRoleNames();
$this->logger->error('Accès denied.', [
'url' => $event->getRequest()->getPathInfo(),
'user' => $userIdentifier,
'isAuthenticated' => !is_null($user),
'roles' => $roles,
]);
}
}