Normally authentication is handled by Symfony nearly automatically – you just need to define and configure your firewalls. Sometimes, however you may want to perform authentication manually from the controller.
Imagine implementing automated login for a user upon visiting a URL like: /autologin/{secret}. I am not considering here the security of such a solution – you are discourage to do it this way, unless the information available for this kind of “logins” is not confidential.

Here is a fragment from my security.yml:

            pattern:    ^/
                check_path: /login_check
                login_path: /login

The actual authentication is very straight-forward. Since I’m redirecting at the end of request, I don’t even need the user to be authenticated in this action. All that is needed is to persist the information about authenticated user to the session. This means storing serialized class that implements TokenInterface. Normally this is done by Symfony framework in ContextListener. In my scenario I’m using form login that uses UsernamePasswordToken, so in short here is what I need to do:

  • Find user
  • Create the Token
  • Store Token in the session

Pay attention to “secured_area” string – it matches the firewall name from the security.yml and is used to create the token and when creating a session key.

     * @Route("/autologin/{secret}")
    public function autologinAction($secret) {
        $em = $this->getDoctrine()->getEntityManager();
        $repository = $em->getRepository('MiedzywodzieClientBundle:Reservation');
        $result = $repository->matchLoginKey($secret);
        if (!$result) {
            return $this->render('MiedzywodzieClientBundle:Default:autologin_incorrect.html.twig');
        $result = $result[0]; 
        $token = new UsernamePasswordToken($result, $result->getPassword(), 'secured_area', $result->getRoles());
        $request = $this->getRequest();
        $session = $request->getSession();
        $session->set('_security_secured_area',  serialize($token));
        $router = $this->get('router');
        $url = $router->generate('miedzywodzie_client_default_dashboard');
        return $this->redirect($url);