0

For the last two days I read through multiple resources on authentication in Symfony2. I think I understand most parts, however I feel that I do not understand the whole thing. I successfully created two authentication providers and a UserProvider but I don't understand how to customize the login process.

What I try to do is writing a REST API that will be consumed by a client that I also write. The client will display a form and sent the credentials via Ajax. Therefore, I don't want to use HTTP basic auth (I don't want a browser window to pop up), I don't want to use OAuth or any token (but use credentials) and I don't want to use a form_login (the login form is rendered by Angular).

Using my custom authentication provider, I can verify that a client is logged in, using a cookie I set in the login controller. However, I don't understand how I would login (or what logged in means in Symfony) a user if I'd try to use the session/Symfony security bundle. I could just avoid all security things from Symfony and roll my own implementation but I would prefer to understand how Symfony expects the authentication provider and the login controller to work together.

What I want is one route where a client can check if it is logged in, login and logout.

GET /session  # return the session if it exists, or 401
POST /session  { session: { email: testy@mctest, password: test1234 }} # login
DELETE /session # destroy session

How would I achieve this in a "Symfony" way? (Bonuspoints for explaining the general authentication concept in Symfony, outside of the authentication provider)

1 Answer 1

1

I'll try to make it the more verbose and simplest that I can from what I personally know :-).

This is what I understood from when I implemented my own Security layer based on the Symfony Security component. If something is not right, please tell me and I will correct it to make it more accurate.

The Security component works with firewalls. A firewall defined a "zone" that is under the responsibility of the Security Component.

For each firewall, you would usually match a pattern that would be matched with the current request. If it matches, then the Security Component tries to determine if the request is allowed to access the resource.

In order to do this, the Security component is divided into two steps :

  • First : authenticate the user. If the user is not authenticated, we cannot authorize him. So the component will go through its Authentication Manager in order to authenticate the user. Authenticating a user in the Symfony way means trying to create a Token (which is actually juste an instance of the TokenInterface class) matching the current request that is going to be authenticated, and then try to authenticate it.

    This Token is supposed to be created thanks to Authentication Listener(s) (classes implementing the ListenerInterface interface). For instance, one will usually use a UserProvider to set a User into the Token object.

    Then, when the token is created, it doesn't mean that the Token is authenticated. This Token will be authenticated thanks to the Authentication Manager. An often use kind of Authentication Managers is based on providers that will check if the credentials (or something else) is wrong with the current token. For example, a DaoAuthenticationProvider will check if the password given with the token user matches with the one in what our users provider gives to us. If not, it fails : either another provider can authenticate the current token, or this will be an authentication fail.

http://symfony.com/doc/current/components/security/firewall.html

  • Second : authorizing the user. For this, I suggest you to read the chapter about it in the Symfony documentation online. You can find it here. It is based on an AccessDecisionManager that will decide if the current user, based on the authenticated token, is now allowed to access the resource. This is usually made thanks to classes called Voters that will vote in order to decide if a user is allowed to access the current resource.

    A voter could vote no, another could vote yes, and another could vote I don't know. The final decision is made from the AccessDecisionManager that will, based on how it is configured, determine if these votes will either allow the user ("Any yes allows the user" or forbid him ("Any no is strict").

I think that this is the basis of what you should understand, to me, about the Security component. Keep in mind that it can be very tricky to understand first, especially for the Authentication part.

Last but not least, I highly recommend you to read this whole chapter : Here !. It is the key and your bible if you want to understand what's happening inside this tricky but awesome component.

Now, for your login issue : what would be useful for you is to check how to create your custom Listener (see the authenticating part of my answer) in order to create your own business logic of "how do I authenticate my user based on the current request". Your form would be an entry point of a firewall zone that would be then pointing to this firewall zone. This listener would check if the information provided by your form is inside the request, and then create the Token. Then, you would have a custom way to authenticate your token thanks to the information you provide.

(Sorry for my english !)

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your response! This describes what I already understood. The Authentication Listener creates a token from information stored somewhere and the token will be authenticated by an Authentication Provider. What I do not understand is in what place should the authentication information be stored and how should it be put there in the controller. Basically, I understood the authentication process but not the login process (or maybe there is no standard way of doing login).
Well, the login process is totally up to you. Remember that for a form login (for example), it's just all about a request sent to a specific page, with some extra parameters which should permit your user to login. What is happening with Symfony is that your form would be sent to a page that is under the firewall control. The firewall would then, thanks to the authentication layer, extract the information from the request and try to authenticate your user. I don't think that you should have any business logic for the authentication layer inside your controllers.
Also, check for what is an entry point according to Symfony : here, it would be the page, not secured by your firewall, that would host your form. Check also for the Exception Listener that will listen to authentication fails and then decide what to do next (like redirecting to the login page again for example).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.