eZ Platform Discussions

Forwarding if no session (on all pages)


#1

Yop

I am setting up an in-house SSO system.
(Constraints related to project partners.)

When an Internet user arrives on the site I must redirect him to the authentication platform to check if he already has an open session.

If it has an open session it is redirected to my site, to a dedicated url, and connected to an appropriate eZ account. (subscriber, unsubscribed, anonymous,…)

Specs :

When loading the page on www.mysite.fr, if no session is previously set up, a 302 redirection is performed on a rebound url of auth.partners.fr.

This non-blocking URL allows you to read the content of the cookie in order to return it to the www.mysite.fr site and thus in the case where a user has previously been identified from another site, retrieve the user context information.

This call should therefore be made when the site is loaded in the event that the session does not exist, and the cookie is not present or no longer valid. The cookie will contain an expiration data, but can be re-verified via the call to the sso/connect url


The question is therefore to know how to connect into the processing of the Internet user’s requests to choose whether to redirect.

Merci pour votre aide :slight_smile:


#2

I think I found where I need to plug myself:

It’s probably on the KernelEvents::CONTROLL

class CkeckSession implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::REQUEST => 'onRequest',
            KernelEvents::CONTROLLER => 'onController'
        ];
    }

    public function onRequest(GetResponseEvent $event)
    {

    }
    public function onController(FilterControllerEvent $event)
    {
        $request = $event->getRequest();
        $session = $request->getSession();
        // TODO
    }
}

It remains to be seen how to know if the user is viewing the site for the first time.


#3

I have succeeded in:

  • Set up my event listener.
  • Finding the necessary conditions for redirection
  • Do the redirection
<?php
namespace MyBundle\EventListener;

use Symfony\Bridge\Monolog\Logger;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Router;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;

class CkeckSession implements EventSubscriberInterface
{
    /** @var string 'https://auth-rec2.client.com'  */
    private $sso_base_url;
    /** @var string 'sso_checked' */
    private $session_var_name;

    /**
     * Pourait aussi être récupérée avec `$event->getRequest()->getSession()`
     * @var Session
     */
    private $session;

    /** @var TokenStorage */
    private $tokenStorage;

    /** @var RouterInterface  */
    private $router;

    /** @var Logger */
    private $logger;

    public function __construct($sso_base_url, $sso_session_var_name, Session $session, TokenStorage $tokenStorage, RouterInterface $router, $logger)
    {
        $this->sso_base_url = $sso_base_url;
        $this->session_var_name = $sso_session_var_name;
        $this->session = $session;
        $this->tokenStorage = $tokenStorage;
        $this->router = $router;
        $this->logger = $logger;
    }

    public static function getSubscribedEvents()
    {
        // https://symfony.com/doc/current/reference/events.html
        return [
            KernelEvents::REQUEST => 'onRequest',
        ];
    }

    /**
     * https://symfony.com/doc/current/components/http_kernel.html#component-http-kernel-kernel-request
     *
     * @param GetResponseEvent $event
     */
    public function onRequest(GetResponseEvent $event)
    {
        if ($this->tokenStorage->getToken() instanceof AnonymousToken) {
            if ( ! $this->session->has($this->session_var_name)) {
                $this->session->set($this->session_var_name, true); // Pour ne pas faire de boucle de redirection

                // L'url de retour de la vérification de la session SSO
                $setCookieUrl = $this->router->generate("sso_setcookie", [], Router::ABSOLUTE_URL);

                // L'url voulue pas l'Internaute. Et donc la redirection aprés $setCookieUrl
                $userUrl = $event->getRequest()->getUri(); // "http://localhost:35080/site_lineaires/developpement/rubrique-1"

                // L'url de la vérification de la session SSO avec la redirection vers la redirection puis la redirection vers la destination
                $url = $this->sso_base_url.'/sso/connect?redirect_url='.urlencode($setCookieUrl.'?redirect_url='.urlencode($userUrl));

                $response = new RedirectResponse($url, 302);
                $event->setResponse($response);
            }
        }
    }
}