Google Authenticator in Symfony2

Before you start reading:
If you just want to add two-factor authentication to your project, you should take a look at scheb/two-factor-bundle. If you’re interested in technical details, keep on reading 🙂


This is the follow up to previous post about two-factor authentication in Symfony2. As promised I also want to show you how to integrate Google Authenticator into your project. If you haven’t read my first post, I’d suggest doing it now, because it explains the principle more in detail. The following example code is widely identical to SonataUserBundle‘s integration.

To get started, you’ll have to install the Sonata Google Authenticator package. If you’re using composer (I guess so), you can simply execute:

Your User entity will need a new attribute to store the secret for Google Authenticator. I’ll name it googleAuthenticatorCode in this example. Also add getters and setters for it.

Once again you have to create a Helper class, which will handle interaction with the Google Authenticator service:

The InteractiveLoginListener will listen for authentication events. If the user has Google Authenticator enabled, it defines an attribute in the session to flag the user with “authentication not completed”.

The RequestListener will listen for any kind of requests. As long as the user session is flagged with “authentication not complete” it will allways show the authentication code dialog. If the request contains a auth code, it checks against the Google Authentication helper class.

The TWIG template is the same as before:

Now finally register all the services:

If you need to generate a secret for Google Authenticator, use the generateSecret() method of the Helper service and store it in the User entity. Then you can fetch the URL of a QR code by calling the getUrl method. If you show it to the user, they can easily add the account to the Google Authenticator app by scanning it from screen.

The My Server in the service configuration is just a label, which will be used in the Google Authenticator app. The account will show up as “username@My Server”.

4 thoughts on “Google Authenticator in Symfony2

  • February 17, 2014 at 18:41
    Permalink

    Hi Christian. Your code has been very useful for me. Thank you very much.
    I have a problem with RequestListener->onCoreRequest method.

    After the user has submitted login login he is redirected to verification code form even if he load a totally public url. Then he is in ambious state. He is not logged (that is right) but he even can access public urls. He can not access any page until he finishs completely the login. I think It would be more friendly if onCoreRequest method only redirect to verification code form if the current page being request required use to be logged.

    What do you think?
    How can I implement that behaivor? any idea?

    Thanks.

    Reply
  • February 17, 2014 at 19:46
    Permalink

    I have added this lines to

    It is only a hot fix. The public route list would be obtained from a service, ACL, …

    Reply
  • February 17, 2014 at 20:31
    Permalink

    I would recommend to block the whole page, because after logging in users are already fully authenticated in Symfony’s security layer. The second step is accually not necessary to become authenticated. It is just an artifical barrier, that we’re building on top of the Symfony security layer.

    That means, if you allow those users access to public pages, they will view those pages as that user, even if they haven’t finished the second step. So if you’re using user data on public pages in any kind of way (e.g. logging, display the authenticated user name), you shouldn’t do this.

    I my projects I’ve forced users to do the second step in order to get access to the page. But I offered a way to cancel the login process. This can be done by adding a link to your logout URL to the authentication form.

    When the logout URL is being called, the user entity will be removed from the session, they will get an unauthenticated session and therefore they will be able to access the page again. This will make sure that only users that completed the whole login process can view the page.

    Reply
  • Pingback: Two-Factor Authentication in Symfony2 | SchebBlog

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.