I write my own webapplication using Spring 3, Spring Security 3.0.5 and Hibernate 3.
I've implemented a login-possibility by using my own UserDetailsServiceImpl, UserDetailsImpl and SaltSourceImpl. I encode my passwords with md5 and a saltsource.
I also have implemented a RememberMe-Service with the Persistent Token Approach.
Now Im really interested in how the login process is working in detail. I read through the Spring Security Documentation several times and I tried to make a conclusion. Some things I do not know for sure so it would be great if you could have a look at it, so that I can correct it.
I also have some more question. Maybe you could have a look at them, so I could complete my conclusion.
I guess this would maybe be interesting for others too, because for beginners it is not so easy to understand how the different components work together and making the conclusion really did take a long time for me.
First I post here my security configuration and after that what I think how login in detail works:
So here is the conclusion: The login-process:
<sec:authentication-provider user-service-ref="myUserDetailsService" >
<sec:password-encoder hash="md5" ref="passwordEncoder">
<sec:logout logout-success-url="/main" logout-url="/j_spring_security_logout" invalidate-session="true"/>
<sec:intercept-url pattern="/admin/**" access="ROLE_ADMIN"/>
<sec:intercept-url pattern="/user/**" access="ROLE_USER, ROLE_ADMIN"/>
<sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY, ROLE_USER, ROLE_ADMIN"/>
<sec:session-management invalid-session-url="/sessionTimeout" session-fixation-protection="migrateSession">
<sec:concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>
<bean id="myUserDetailsService" class="project.business.logic.UserDetailsServiceImpl">
<property name="projectDao" ref="projectDao"/>
<bean id="saltSource" class="project.business.logic.SaltSourceImpl">
<property name="projectDao" ref="projectDao"/>
<bean id="projectDao" class="project.backend.hibernate.HibernateDao">
<property name="sessionFactory" ref="sessionFactory"/>
<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"/>
<!-- securityDataSource is defined in another xml-File by using an org.apache.commons.dbcp.BasicDataSource -->
1. User calls page which contains login formular
2. User types in username and passwords and sends formular to server
3. Server receives an Http Post Request for this url (j_spring_security_check). This url is monitored by the UsernamePasswordAuthenticationFilter.
4. UsernamePasswordAuthenticationFilter calls AuthenticationManager and gives him an UsernamePasswordAuthenticationToken, which contains Username and Password
5. AuthenticationManager is now working on the authentication:
5.1 he creates with the class UserDetailsServiceImpl an UserDetailsImpl object, which contains username, password, granted authority (and more). this informations are requested from the database.
5.2 then the UsernamePasswordAuthenticationToken and the UserDetailsImpl object are compared with each other.
5.3 if the passwords are equal, an Authentication object is created and it is given to the SecurityContextHolder. The User is authenticated now!
If the passwords are not equal, no verified authentication object can be created and an error messages is given back to the user.
is it correct so far? some questions are still existing:
- after authentication for the login-process, must the user be authorized to see if he's got the right to call the page which is loaded after login? so does an authorization-process start after this login-process?
- if someone must be authorized and is already authenticated, the UsernamePasswordAuthenticationFilter is not called anymore. Spring Security just takes a look into the SecurityContext, if it contains an verified Authentication-Object, right?
so for every request, which is send to the server, spring security first looks at the security context and then handles authorization?
- is 5.1, 5.2 and 5.3 done by the AuthenticationProvider? (it is an DaoAuthenticationProvider, right?) or by the AuthenticationManager - or by both? which part is done from whom?
- at which point is the SaltSource loaded to compare the password? who calls the getSalt()-method from SaltSourceImpl? is then the password from the user encoded or the password from the database decoded to compare the two?
- where is the RememberMeFilter called? When a request is send to the server containing a cookie? for example if the user calls the login page - if he does not send a cookie, the remembermefilter is not called, otherwise he is? when he is called, an Authentication Object will be loaded in the SecurityContext. where does this authentication object come from, must it first be created, like it is created by the login-process?
It would be great to get some answers to it! thank you! :-)