Answer the question
In order to leave comments, you need to log in
Is it possible in symfony to check if a certain role has access to a url address?
I have such a task. After the user exits the application, it is necessary to redirect him to the page on which he pressed the "Exit" button, but first you need to check whether anonymous users have access to this page, if not, then redirect to the main page.
After authorizing the user, I can easily transfer him to the page from the referer parameter or header:
public function index(Request $request):RedirectResponse
{
// ... authenticate
$referer = $request->request->get('referer') ?? $request->headers->get('referer');
if($referer === null){
$this->redirectToRoute('main');
}
return new RedirectResponse($referer);
}
public function index(
Request $request,
RouteMatcherInterface $routeMatcher,
):RedirectResponse
{
// ... exit
$referer = $request->headers->get('referer');
if($referer === null){
$this->redirectToRoute('main');
}
if($routeMatcher->has($referer)){
$router = $routeMatcher->get($referer);
/**
* $router->getName(); // string
* $router->getParameters(); // array
* $router->isGranted('IS_AUTHENTICATED_ANONYMOUSLY'); // bool
*/
if($router->isGranted('IS_AUTHENTICATED_ANONYMOUSLY')){
new RedirectResponse($referer);
}
}
return $this->redirectToRoute('main');
}
Answer the question
In order to leave comments, you need to log in
It's easier to go the other way.
- when exiting, we mark this fact in the session
- if after the redirect it catches access-denied and the flag is present, then we simply redirect to the main
one - remove the flag as soon as the user has landed on the page with 2XX code, so that in the future he will be redirected to the login page
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Http\Event\LogoutEvent;
class LogoutRedirectSubscriber implements EventSubscriberInterface
{
private const KEY = 'logout';
private UrlGeneratorInterface $urlGgenerator;
public static function getSubscribedEvents()
{
return [
ExceptionEvent::class => ['onException', 2], // Before \Symfony\Component\Security\Http\Firewall\ExceptionListener
ResponseEvent::class => 'onResponse',
LogoutEvent::class => 'onLogout',
];
}
public function __construct(UrlGeneratorInterface $urlGgenerator)
{
$this->urlGgenerator = $urlGgenerator;
}
public function onException(ExceptionEvent $event): void
{
if (!$event->isMasterRequest()) {
return;
}
$exception = $event->getThrowable();
if (!$exception instanceof AccessDeniedException) {
return;
}
$session = $event->getRequest()->getSession();
if ($session->has(self::KEY)) {
$event->setResponse(new RedirectResponse($this->urlGgenerator->generate('index')));
$event->stopPropagation();
}
}
public function onResponse(ResponseEvent $event): void
{
if (!$event->isMasterRequest()) {
return;
}
if ($event->getResponse()->getStatusCode() >= 300) {
return;
}
$session = $event->getRequest()->getSession();
if ($session->has(self::KEY)) {
$session->remove(self::KEY);
}
}
public function onLogout(LogoutEvent $event): void
{
$event->getRequest()->getSession()->set(self::KEY, true);
}
}
options
and check them in the handlerLogoutEvent
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question