<?php
/*
* Friendu_Frontend // AccessDeniedSubscriber.php
*
* (c) 2018 Carsten Zeidler
*/
namespace App\EventListener;
/**
* Description of AccessDeniedSubscriber
*
* @author Carsten
*/
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Http\Firewall\AccessListener;
use Symfony\Component\Security\Core\Security;
class AccessDeniedListener implements EventSubscriberInterface {
protected $router;
protected $security;
public function __construct(Router $router, Security $security) {
$this->router = $router;
$this->security = $security;
}
public function onKernelException(GetResponseForExceptionEvent $event): void {
$exception = $event->getException();
if ($exception instanceof AccessDeniedException && !self::isThrownByFirewall($exception)) {
// Create your own response like in a custom access denied handler
if ($user = $this->security->getUser() === null) {
$response = new RedirectResponse($this->router->generate('login'));
} else {
$response = new RedirectResponse($this->router->generate('account_home'));
}
$event->setResponse($response);
$event->stopPropagation();
}
}
public static function getSubscribedEvents() {
return [
// Define the priority to execute our subscriber before the one from the security component
KernelEvents::EXCEPTION => ['onKernelException', 10000]
];
}
/**
* Determines, by analyzing the stack trace, if an exception has been thrown by the firewall.
*/
private static function isThrownByFirewall(\Throwable $exception): bool {
foreach ($exception->getTrace() as $stackItem) {
$class = $stackItem['class'] ?? null;
if ($class === AccessListener::class) {
return true;
}
}
return false;
}
}