I have a typical Spring MVC running on Tomcat. After switching the system to run on HTTPS (everything is working OK under plain HTTP), the login stopped working. The reason is that Spring's SecurityContextHolder.getContext().getAuthentication()
object becomes null
after RedirectView
is used.
I already searched for the answer, the only one I found suggested to set property redirectHttp10Compatible
to false
in the viewResolver
bean setup. This did not help.
I also checked that throughout redirect, my session id remains the same and the connection remains secure, i.e. it is not an issue (at least as far as I could tell) of a change between http and https or vice versa.
What could be the problem?
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http auto-config="true">
<intercept-url pattern="/**" requires-channel="https" />
<intercept-url pattern="/index*" access="ROLE_USER"/>
<intercept-url pattern="/dashboard*" access="ROLE_USER" requires-channel="https"/>
<intercept-url pattern="/login*" access="ROLE_GUEST, ROLE_ANONYMOUS, ROLE_USER"/>
<intercept-url pattern="/signin*" access="ROLE_GUEST, ROLE_ANONYMOUS, ROLE_USER"/>
<intercept-url pattern="/signup*" access="ROLE_GUEST, ROLE_ANONYMOUS, ROLE_USER"/>
<form-login login-page="/home"
default-target-url="/home"
authentication-failure-url="/home?authentication_error=true"
authentication-success-handler-ref="redefineTargetURL"
/>
<anonymous username="guest" granted-authority="ROLE_GUEST" key="anonymousKey"/>
<logout invalidate-session="true" logout-success-url="/logout?message=Logout Successful" />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsService" />
</authentication-manager>
<beans:bean id="redefineTargetURL" class="com.groupskeed.common.RedefineTargetURL" />
<beans:bean id="userDetailsService" class="com.groupskeed.security.UserDetailsServiceImpl" />
The HttpServletRequest.getUserPrincipal() will return the result of SecurityContextHolder.getContext().getAuthentication() . This means it is an Authentication which is typically an instance of UsernamePasswordAuthenticationToken when using username and password based authentication.
Yes, it's thread safe with the default strategy ( MODE_THREADLOCAL ) (as long as you don't try to change the strategy on the fly).
The SecurityContextHolder.getContext().getAuthentication()
becoming null after redirect is correct since it is threadbound. But it should be repopulated from the session. Therefore try to keep track of the SPRING_SECURITY_CONTEXT
Attribute in the Session. Here is some example code to get an idea:
HttpSession session = request.getSession(true);
System.out.println(session.getAttribute("SPRING_SECURITY_CONTEXT"));
In the Spring Security documentation there is a Part about how HTTPS/HTTP switching can screw up the session perhaps there is a hint to your problem somewhere in there. http://static.springsource.org/spring-security/site/faq.html#d0e223
The above FAQ leads to an examination of how the session is handled in your application. I probably would start looking at the AuthenticationSuccessHandler implementation. (You can post it into your question if you like.)
For more detail on how the security context is handled in web applications see the following: (section 5.4 Authentication in a Web Application): http://static.springsource.org/spring-security/site/docs/3.0.x/reference/technical-overview.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With