feat: catch access denied exceptions with listener

This commit is contained in:
Björn Fromme
2024-02-28 10:50:23 +01:00
parent 658d55813f
commit feea4592c5
@@ -0,0 +1,48 @@
<?php
namespace App\EventListener;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
#[AsEventListener(event: KernelEvents::EXCEPTION, method: 'onKernelException', priority: 2)]
class AccessDeniedListener
{
public function __construct(
private readonly Security $security,
private readonly LoggerInterface $logger,
private readonly UrlGeneratorInterface $urlGenerator
) {
}
public function onKernelException(ExceptionEvent $event): void
{
$exception = $event->getThrowable();
if (false === $exception instanceof AccessDeniedException) {
return;
}
$request = $event->getRequest();
if ($request->isXmlHttpRequest()) {
return;
}
$request->getSession()->getFlashBag()->add('error', 'Zugriff verweigert');
$this->logger->warning('Access denied', [
'uri' => $request->getRequestUri(),
]);
$user = $this->security->getUser();
$redirectRoute = $user ? $user->getDefaultRoute() : 'app_login';
$event->setResponse(new RedirectResponse($this->urlGenerator->generate($redirectRoute)));
}
}