0

I'm working on a Symfony 2.7 project and I'd like to redirect users on a specific page if their session expires. I created a Listener that checks roles and routes and if a user is trying to access an authenticated route without being authenticated i redirect to the specific page. This is not working for the moment because the default redirection to homepage has an higher priority.

This is the listener:

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Routing\Router;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;

use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;

class UserDisconnectionListener
{
    protected $router;
    protected $security;
    protected $tokenStorage;

    public function __construct(Router $router, AuthorizationChecker $security, TokenStorage $tokenStorage)
    {
        $this->router = $router;
        $this->security = $security;
        $this->tokenStorage = $tokenStorage;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        $request = $event->getRequest();
        $loggedRoutes = ['user_account', 'user_index', '...'];
        $url = '';

        if($this->tokenStorage->getToken() !== null) {
            if(!$this->security->isGranted('IS_AUTHENTICATED_OPENID')) {
                if (in_array($request->get('_route'), $loggedRoutes)) {
                    $url = $this->router->generate('disconnection_route');
                }
            }

            if(strlen($url) > 0) {
                $response = new RedirectResponse($url);
                $event->setResponse($response);
            }
        }
    }
}

app.userroute.listener:
    class: app\UserBundle\Listener\UserDisconnectionListener
    arguments: ['@router.default', @security.authorization_checker, @security.token_storage]
    scope: request
    tags:
      - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

Is there a better way to do it ? I tried to use priority tag but i don't which priority set. I tried to log and when i tried to access 'user_index' route my listerner log said that i was already redirected on the homepage 'general_index' route.

PS: I'm using FOSUserBundle coupled with an OpenID Bundle.

  • Please read this post, it may help you https://stackoverflow.com/questions/22232587/how-to-auto-redirect-a-user-in-symfony-after-a-session-time-out. What is the 'IS_AUTHENTICATED_OPENID' ? – Mcsky Aug 22 '17 at 07:16
  • If I understand it well: `````` will refresh the page and ```SessionIdleHandler``` will allow me to check if user is still logged in and redirect if he's not ? – Quentin Lerebours Aug 22 '17 at 07:29
  • IS_AUTHENTICATED_OPENID is a role meaning that user is authenticated – Quentin Lerebours Aug 22 '17 at 07:37
  • Yes the sessionIdleHandler is defined in this post https://stackoverflow.com/questions/18872721/how-to-log-users-off-automatically-after-a-period-of-inactivity . The session handler clear the server session here but you are not forced too. – Mcsky Aug 22 '17 at 07:50
  • Thanks for your answer, but i think that using SessionIdleHandler will not be different than what i was doing. If a user refresh before the browser do it itself (and the session is lost) the SessionIdleHandler won't be called and the user won't be redirect where i want. Do you agree ? – Quentin Lerebours Aug 22 '17 at 09:00

1 Answers1

0
tags:
  - { name: kernel.event_listener, priority: -256, event: kernel.request, method: onKernelRequest }

https://symfony.com/doc/2.7/event_dispatcher.html check the symfony documentation for events, and search for priority

This tag option specify to symfony in which order he haves to call listeners.

It isn't the best way to 'hardcode' the list of authenticated routes, if you forget to add one your code won't work. You should try to retrieve dynamically the authenticated routes

Mcsky
  • 1,426
  • 1
  • 10
  • 20
  • I tried with -2000 to be sure and it didn't work. I also tried -256 and it's not working, the redirection on homepage seems to have the priority – Quentin Lerebours Aug 22 '17 at 07:10
  • I agree that it should work, but i logged the route that was called when the listner was executed and its the homepage, do you have an idea why its not working ? – Quentin Lerebours Aug 22 '17 at 09:13
  • I think it's the authorization part of Symfony that is redirecting you to homepage, this code is executed at a high level level. I don't know how to override it but you may should search in this way. Should I remove my answer ? – Mcsky Aug 22 '17 at 09:16
  • Take a look at this https://symfony.com/doc/current/reference/configuration/security.html. You could try the `firewalls.yourfirewall.access_denied_handler : 'serviceId'` configuration maybe you can do your stuff here – Mcsky Aug 22 '17 at 09:19