Using Spring Security I have a DaoAuthenticationProvider described like here:
http://static.springsource.org/spring-security/site/docs/2.0.x/reference/dao-provider.html
I also have caching (also like it's described in that article).
The problem is that when a request comes in with a good username (that is already in the cache), but a bad password - it returns the user from the cache as if it is a good username/password. Because it uses the username as the key, the password is not involved at all.
The exact code that returns the user from the cache:
UserDetails user = this.userCache.getUserFromCache(username);
Did anybody ever dealt with this problem before? I can also check if the password is the same, but it would be a custom thing.
Thank you.
If you configured your application with the standard components, the scenario should be as follows:
At user request arrival the Authentication object is created and populated with username and password supplied by user.
User details are retrieved: if it's possible, UserCache is used to retrieve previously cached user details (i.e. getUserFromCache is called either by implementations of UserDetailsService or AuthenticationProvider before the call to AuthenticationManager is performed). And it is 100% OK that the user details from cache will come with the good password.
After basic pre-authentication checks (credentials expiration etc.) the actual authentication occurs. At this point the password from cached user details is compared to the password stored in Authentication object supplied (which currently contains the wrong password). At this point authentication attempt fails.
However, if you implement your own AuthenticationProvider or AuthenticationManager, you are responsible for password checking.
What's the code that originally gets the user from the DB and caches it? Does it check the password? Sounds like you have an abstraction issue - Spring Security should not know where the user is coming from (DB or Cache) and should use the same logic either way.
Related
first post here, hope im doing right.
In a project, we have a scenario where we have a single web application with multiple entities. Currently, the login is managed via default JDBC Spring Security provider, working fine.
For a new requirement, we need that each entity can have their own login method (currently 2 methods would be available, the JDBC one, which is the current one, and the second method would be authentication via SAML, with each entity defining their own IdP, but this is another story)
I need some guidelines on how this can be achieved, I have done some search and I have found providers for different URL's, etc... But not different login methods for the same app and url's depending on the user type or entity.
Is a good approach to have a custom single entry point where we can check the entity user and then use the suitable authentication provider?
Kind regards,
Alex
As each of your users might be using a different IDP you will in any case need to determine the username before proceeding with initialization of the authentication process - but you already know this.
One approach to take (similar to what Microsoft is using with the Office 365 for corporate users) is:
display a login page with fields for standard username + password
once user enters username and blurs the input field, you make an AJAX call (to your custom API made for this purpose) and fetch information about authentication type + IDP to use for this user
in case the type is password you simply let user continue with filling in the password field and POST to the same place as you're used to for processing with the JDBC provider
in case the type is federated authentication you initialize authentication with the correct IDP by redirecting to /saml/login?idp=xyz and continue with the SAML flow
It's possible to avoid any APIs by submitting the form once user enters the username, or let user click a "Continue" button. It would then make sense to use a custom EntryPoint which:
redirects user to the main login page in case it wasn't provided with a username
displays either login page with username/password or redirects to the correct IDP, once username was provided
Please help me on this.
void setCreateSessionAllowed(boolean createSessionAllowed)
method of
org.springframework.security.web.savedrequest.HttpSessionRequestCache
class says
If true, indicates that it is permitted to store the target URL and exception information in a new HttpSession (the default). In situations where you do not wish to unnecessarily create HttpSessions - because the user agent will know the failed URL, such as with BASIC or Digest authentication - you may wish to set this property to false.
So I did not understand the description properly, also we are using a product and its documentation says setting it to false will disable the creation of anonymous user sessions.
So my question is, session creation and associating it with a request is servlet container's job. So How come using this method(setCreateSessionAllowed) will not create a session.
Please validate my understanding, is it correct or not. also
setCreateSessionAllowed(false), will JSESSIONID be created or not?
The HttpSessionRequestCache saves the last URL requested by the client in a user session.
This is used by spring security, when it redirects you to a login page, to restore the url after a successful login.
In case of basic or digest authentication is directly authenticated or asked to resend the request with the credentials. Therefore URL caching is not necessary.
If setCreateSessionAllowed is set to true, it will by default create a session to store the last url.
If set to false it will only support this feature if a session is already is created.
If no url is stored, spring security will use the default target URL supplied in the spring security configuration.
As for your last question, it is not directly obvious to me how it will affect the anonymous login feature of your mentions product.
I'm using Spring security 3.x. In my login page, there is an additional field that the user would scan an ID card to populate. If they do this, the username is not required (it is looked up against the ID scanned), but the password still is.
The problem is that the username is required by my custom AuthenticationProvider. The ID is captured in a filter before this (UsernamePasswordAuthenticationFilter). I don't know how to connect them so my AuthProvider knows it doesn't require username (and also, how does it get the ID at this point since it is passed an Authentication object?).
You might need a special kind of Authentication interface that is not a UsernamePasswordAuthenticationToken and hence doesn't require the username and password both.
Then your AuthenticationProcessingFilter/AuthenticationProvider may create one of them.
Have a look at spring-cas-client and CasAuthenticationToken as an example.
The filter I was extending was FORM_LOGIN_FILTER, which is correct, however I needed to perform all the retrievals (j_username, j_password) here and call the authentication manager manually, instead of calling the super() method which passes the retrievals and auth manager calls to Spring. This also required extending the UsernamePasswordAuthenticationToken. Once I do this, they are connected.
I am reading the doc Spring 3.1 security documentation extensively, but I can't find answers to all my questions.
In a spring web application, based on form login (user + pwd), I want to salt user passwords with SHA-256, using a random salt for each user. This means I have to save the salt and the hashed password in my database for each user. No issue so far.
It seems clear that I have to implement my own UserDetailsService to fetch my user information's from my database and configure it in my spring-security.xml.
It seems like I will have to add an extra getSalt() method on top of my implementation of UserDetails to make it available when checking the login provided by the user against the stored hashed password.
Then the situation becomes unclear. I should intercept login requests. From section 6.4.3, it seems like Spring will map the user submitted credentials to an Authentication object and submit it to an AuthenticationManager.
My questions are:
i) What implementation of Authentication will Spring submit to the AuthenticationManager? How do I retrieve the name and password?
ii) It seems like I would have to implement my own AuthenticationManager. At each call of authenticate(...), I would fetch the login name and password, fetch UserDetails from the database. Then, hash the provided pwd with the corresponding salt and compare with the database hashed item. Correct?
iii) The AuthenticationManager API also has a supports(...) method. How should it be implemented?
iv) How should Authentication and AuthenticationManager be configured?
I must not be reading your question properly, but Spring Security offers salted passwords out of the box:
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/core-services.html#d0e3021
If an 8-bit salt is insufficient, you are able to inject your own SaltSource into the DaoAuthenticationProvider. The manual actually strongly recommends this.
I have an application deployed on WebLogic 10.3.2 (11g), in which the user logs in through SSO. In other words, if the user is not logged in, he is redirected to SSO, where he logs in, and then is redirected back to the application. The whole redirection takes place by an the Oracle HTTP Server (a modified apache), which makes sure that only SSO-authenticated users can see the applciation.
So, when the user finally sees the application, he is already logged in.
Is there a way to use Seam security with this scenario? What I would like is to use the roles of the Subject to restrict access to certain pages and components.
A way I thought of, but for which I am not sure, is to use the subject that is populated by the SSO authentication provider of WebLogic, and use it to populate the Identity component of Seam. That would take place in the authentication method, which will always return true (since the user is already logged in). Inside the method, the credentials and roles of the Subject will be "transfered" inside the Seam identity.
Is this feasible at all?
Cheers!
You could write your own authenticate method, or override the Identity class and the login() method to achieve this. I've done something similar with a reverse proxy that performed our authentication. In the scenario, the proxy sent back the user ID of the authenticated user and all the groups they were a member of as header values. I wrote a filter to intercept the headers and then used my custom Identity class to do the rest.