Manually authenticate Symfony 2 user

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:

security:
    firewalls:
        secured_area:
            pattern:    ^/
            form_login:
                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);
    }
  1. Hi, thanks for your post, I found it very useful when I needed to do something like that, in a non Symfony application, using symfony’s components.

    Working within a Symfony2 application you should consider the implementation of a custom security provider, is not that complex and is a much better solution. I’m writing something about it ’cause I’ve done it a few days ago.

    Thank you again for your post :D

  2. It’s better to use security.context service and setting token there

    $this->container->get('security.context')->setToken($token)

  3. Thanks for the helpful blog entry. “calss” is misspelled. :grin:

  4. Interesting, I have one question. How does this script know which user to get from the DB?

    is the $secret the users email?

    I’m trying to log the user in automatically after registration

Leave a Comment


*


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">