My Symfony (4.4) app uses the OneloginSamlBundle bundle to authenticate users against a SAML identity provider. This works fine. I receive the SAML response and the User Provider instantiates my User class correctly. However, I want that once I get the authentication SAML response, the corresponding user is instead fetched from my database. How could I do this ?
I guess I need to create a custom user provider which would use the OneloginSamlBundle userprovider AND then fetch the user, but I don't know how I am supposed to do it with Symfony.
I am trying to use the following:
1) form_login_ldap just for user authentification
2) A custom UserProvider for retrieving user roles from a MySQL database
Everything seems to work fine: I am able to login, the roles are used etc.
As soon as I change the roles in the database, isEqualTo() kicks in - the user is redirected to the login page. There the browser hangs in an endless loop. After using tcpdump I realized that form_login_ldap is trying to authenticate the user without a password.
I think I am generally missing the point how the password will be handled in this scenario. My UserProvider can't retrieve an (encrypted) password as he is querying MySQL and the user is authenticated using LDAP.
If the "refreshUser function of my UserProvider returns a new user object with the new roles, the password seems to be lost.
If within the UserProvider i just modify the array of roles for the user, the web application does not recognize that and old roles apply (I guess the session must be updated?).
How are form_login_ldap and my UserProvider supposed to interact? How do I make sure that upon "refreshUser" the password is still available?
What am I missing for my general picture?
I am trying to perform an automatic login when the user clicks a link in their email with Spring Security.
I have seen a lot of examples to perform a programmatic login like the following:
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
try {
Authentication auth = authenticationManager.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(auth);
repository.saveContext(SecurityContextHolder.getContext(), request, response);
rememberMeServices.loginSuccess(request, response, auth);
....
The problem I see is that I do not have the original password so I can't create a UsernamePasswordAuthenticationToken. Any other way to login the user if I do not have the plain text password (I have the one that is encoded)?
Thanks in advance.
Be careful that you know what you are doing in terms of allowing login from a link within an email. SMTP is not a secure protocol and so it is typically bad to rely on someone having an email as a form of authentication.
You do not need to use the AuthenticationManager if you already know they are authenticated. Instead you can just set the Authentication directly as shown below:
Authentication authentication = new UsernamePasswordAuthenticationToken(user, null,
AuthorityUtils.createAuthorityList("ROLE_USER"));
SecurityContextHolder.getContext().setAuthentication(authentication);
If you want a complete example, you can refer to the SignupController in the secure mail application that was the basis for Getting Started with Spring Security 3.1 (InfoQ video of presentation).
I am reading on form authentication in ASP.NET and cannot understand some moment:
James enters a username-password, they are saved in the db. A cookie from username is created, encrypted and attached to a response. As I understand then, when we get a request we need to recognise that cookie received are from James and so we can show his customised page.
What I would like to understand is how system will retrieve username form cookie and then load his info from db?
Forms Auth is storage agnostic. It doesn't have to use a database, indeed you can use it with usernames and passwords in web.config.
So what happens is
A user logs in.
The user is authenticated against the membership provider (which can use SQL, Active DIrectory, web.config, Oracle, MySQL, whatever)
A forms authentication token is created for the user, and is placed on the user machine via a cookie.
Each subsequent request reads the forms authentication token, and queries the provider to get the user details.
The user details are used to populate the user identity in the HttpContext and current thread for the request which is then available to your code to use.
In your code you can check the User property in the Page class (WebForms) or the User property in the controller class (MVC).
While you can get at it via the current thread, or the current context it's not advised, especially once you start using background tasks, where the identity may not propagate to the thread, or the context may change.
You'll note that nothing is stored in a database when the user logs in. It's all in the forms authentication token, and the work of retrieving the user from it's store on each request is done for you.
Afaik Forms Authentication does not store or load anything in any database. You can use a database to store the username and password, or you can put them in the web.config. How you store user credentials and validate them is up to you, and can happen separately from Forms Authentication.
Once you have validated a user (against database or some other logical storage), you use FormsAuthentication to write the authentication cookie. You do not need to worry about decrypting the cookie.
You can get the username from System.Threading.Thread.CurrentPrincipal.Identity.Name. To retrieve user's info from the database, you would query the database using the value if the principal identity name.
Response to comments
Right, you can use forms authentication with the membership provider, active directory, or your own custom user database. FormsAuth doesn't care about the password at all, unless it is stored in web.config (as noted in blowdart's more complete answer). It just writes the cookie, which is decrypted and used to create the thread identity automatically.
Additional Info
Even though this was marked as the answer, blowdart's response is much more complete. You really should not get the identity from the thread if you need it in an ASPX page or MVC controller, use the properties he referenced.
You get the username in your web form by calling User.Identity.Name, e.g. like this:
protected void Page_Load(object sender, EventArgs e)
{
string userName = User.Identity.Name;
}
ASP.NET interprets the cookie for you, you don't have to read it yourself. Or is your question how to store the user and password in the DB?
To authanticate users in Asp.net Membership we can call method
FormsAuthentication.Authenticate(username, password)
how can I do the same job (generate session, cookies and all other staff that Authanticate does) without users password?
I'm trying to login user over facebook connect. User's facebook id is stored within the users data. User should be signed in like a normal user.
I think you can use the SetAuthCookie method.
more info here http://msdn.microsoft.com/en-us/library/system.web.security.formsauthentication.setauthcookie.aspx