In the above, the Parameter arg0, is the username entered by the user, you can execute the query to search from the database using this username, and you can return an User object, by adding all the required details like password and roles for this user, Spring security will take it on from here..
The nice thing about Spring Security is that any small part of it can be customized while using all the other built in functionality. The bad thing about that is that there are a bunch of smaller pieces that are responsible for their own part of the whole Security solution.
So Spring Security has the following
1) AuthenticationManager - handles logging in stuff. Mostly delegates to the following classes
a) UserDetailsService - the auth manager calls the UserDetailsService loadUserByUserName(String userName) to get the data for the user from any source. Could be database, LDAP, OAuth, SingleSignOn, ActiveDirectory or other locations. This method returns
b) UserDetails - this is the User object it stores the username, password a few booleans as well as an array of GrantedAuthority objects. These
c) GrantedAuthority objects hold the roles that the user has.
d) RememberMeService - if you want a remember me service with cookies, then this interface does that work. So the AuthenticationManager might first delegate to a RememberMeService looking for a cookie that has the value of the userName. If it doesn't find one, then the AuthenticationManager delegates to the UserDetailsService. If there is a cookie, the RememberService reads the cookie to get the userName then calls the UserDetailsService to look up the user data.
After the AuthenticationManager gets the UserDetails object it then has all the information for the user.
So in your implementation of UserDetailsService you can call anything that you want. If it is in a database, but your tables don't match the built in JdbcUserDetailsService, then you can still use the JdbcUserDetailsService implementation and just override the user-by-username-query and the authorities-by-username-query with queries that match your table structure.
You just have to make sure that the user-by-username-query returns three fields. 1) the userName 2) the password 3) boolean for is the user active. If you don't have an active field, make your query always return true for that third field. For the authorities-by-username-query, it has to return two fields. 1) username 2) role name prefixed with "ROLE_", you will have a row for each role that the user has. So if the user is assigned three roles, then three rows should be returned. Once you have that data, you just create and populate a UserDetails object. Again this is an interface that you could implement your own if you want it to store more than the Spring Security standard, or just use the built in class that is in the Spring Security jars.
Hope that helps you clear the authentication hurdle.
Thanks Prasad, I cleaned up the method to populate the user object but it just goes back to the login page. I have two questions basically
1. I don't want Spring to go to the login page since the user id is already available in the session.
2. Did I populate the user object incorrectly or is it incomplete.
You just have to make sure that the user-by-username-query returns three fields.
Mark, Do I really have to use the user-by-username-query query ?
Joined: May 28, 2008
It is successful if I enter rod/koala in the UI but if I enter any other values it just goes back to the login screen. Why does this happen, is there a way to directly go to the loadUserByUsername and authenticate.
Well, I already have an existing authentication(Siteminder) done and the userid is available in the request header. I would like to pick up that userId and hit the database to check if the user has access to this screen.
I basically don't want to direct to the default Spring login form since I am already logged in.
Users having access to screens, should be configured in security context xml file. This UserDetailsService class is called to authenticate/authorize the users.. Spring security creates a session after this. If you already have a authentication code, can you explain why you are using Spring Security again? Are you trying to implement SSO?
If you already have a authentication code, can you explain why you are using Spring Security again?
I already have a authentication done as mentioned earlier (Siteminder). However, I want Spring security to help me validate some URLs which are links within the application but can be directly accessed once the authentication is complete.
The UserDetailsService class is only used to load User data for Authentication. Authorization is a different piece all together.
So now we know enough information. You want to use SiteMinder for the user data. So a Google search has shown me this
I tried a little bit of preauthentication and I realized that it is not exactly what would fit my use case. Basically Spring security is like the second line of defense tracked against a database security table that I have. Is this a form of authorization ?
Can I authorise the url by using UserDetailsService without going through Spring security login and also is it possible to hit the database against a value present in the session.
I don't think I would have trouble building the UserDetails or the GrantedAuthorityImpl objects. Still not sure why I should use user-by-username-query, if I can populate GrantedAuthorityImpl myself.