Stateless authentication in Symfony 2

Everyone these days want’s an API. Mostly for some SPAs or for external applications. Common issue here is a security layer where you can’t use standard form and cookies. Other thing about state saved in cookies is f.ex. clickjacking. James Ward wrote about this some time ago.

So we have some requirements:

  • Authentication based on token
  • Token is send as part of each request to make API stateless
  • I want to be able to use Symfony Security layer as I do in “normal” applications
  • Bonus: I want authenticate each device with different token (when someone is using app on PC and phone in the same time)

So I went to Symfony Cookbook and I’ve found solution with my requirement in the title. And it wasn’t what I needed. OK, it’s about keys/tokens and probably I could make it working but I have a lot of free time during holidays so I can do better. So I went one article further to write my my own authentication provider. And there is of course article about it too.

Lets start with UserProvider. What I want is find User entity with given token and device identifier. Simple schema looks like this:

User and Identities

To find user I query by username when authenticating user by token and device on the beginning of each request and once in a while by username and password to create new Identity.

Interface like this is everything I need and it’s consistent with Liskov’s substitution principle (L in SOLID).

When I can find user all I need is follow Cookbook and everything is working great. SecureApiBundle is available on GitHub┬áso you can check how I’ve done this.

Update your composer.json file

enable it

and use secure-api in your security config:

I know it is possible to add paths for registration and session creation to config, but for now I don’t need this so I keep it simple :P Doctrine UserRepository is used here as User Provider with interface I mentioned earlier. Line 28 is marker that we are using our token solution for this firewall.

 

3 Replies to “Stateless authentication in Symfony 2”

  1. Hi. This seems to be what I need. However, as far as I can see, you haven’t gone into detail as to what is required to complete this.

    For example, I assume that wherever login is handled needs to
    (i) create an identity
    (ii) return the token

    You also don’t specify the header structures required – from looking at he code, am I correct that the headers should be
    “Authentication” == the token
    “user-agent” == the device identifer

    1. I left creation of identity, because it wasn’t related as much with Security as I thought is relevant to Security layer. And IMO it’s bad to force some solutions when it’s relatively simple to create them from scratch in few hours.

      About headers – yes, in “Authentication” you send the token and User-Agent header is send by every browser and device itself. It’s used to reuse token on device and be able to logout from other devices.

      I have a bit improved version of this bundle in few of my current projects so there should be another post about this soon.

Leave a Reply