phpsymfonysaml-2.0symfony-3.4

Symfony redirect user BEFORE logout event


I have a Symfony 3.4 project (with FosUser if this helps) with multiple login types (local,Oauth2,ldap) that all logouts (in the end) are handled from a local user via the default logout method.

In SAML protocol however the logout needs to take place with redirect to Idp (Identity provider, here the Azure AD) take the success response and logout the user local.

In my online search only this documentation for 5.1 symfony (and not for 3.4) https://symfony.com/blog/new-in-symfony-5-1-simpler-logout-customization explains how is possible to trigger some code before logout event happen and not after (like a logout listener or subscriber does).

How is possible for a 3.4 Symfony project to check if the login type of a user is saml or not BEFORE the logout event happens? If it is saml, can I redirect him to Idp (and back to custom route) and continue the process?


Solution

  • Thanks to @Jakumi comments i manage to run a listener before the default LogoutListener. First i have to register in services.yaml a listener with priority above 7

    App\EventListener\BeforeLogoutListener:
      tags:
        - { name: kernel.event_listener, event: kernel.request, priority: 8 }
    

    Here i can't use appHelper or Security to get the current user because this listener runs BEFORE the Security/Http/Firewall. So i stop the event propagation setting new response, redirect the user too a custom logout router and THEN do my validation logic in the user.

    public function onkernelRequest(GetResponseEvent $requestEvent)
    {
        //Get data from Database and validate this action
    
        if ($requestEvent->getRequest()->getPathInfo() === '/logout' &&  $isExternalLogout) {
                $requestEvent->setResponse(new RedirectResponse($this->router->generate('external_logout')));
        }
    
    }
    

    I hope I saved days from someone who was struggling to do the same.