13

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" />

riddle_me_this
  • 8,575
  • 10
  • 55
  • 80
Dima Suba
  • 263
  • 1
  • 3
  • 9
  • Have you tried accessing it via the session? Also please post your configuration to help further debugging. I would look into the attachment of the Authentication between the Session and SecurityContext. – Carsten Jun 06 '13 at 09:43
  • Thank you for reply. Which configuration files should I post? – Dima Suba Jun 08 '13 at 23:24
  • The Spring Security Configuration. And if you use any custom class implementations these might be helpful too. – Carsten Jun 10 '13 at 07:13
  • Here it is. After authentication, user gets redirected to /dashboard. It is during this redirect the Authentication object becomes null. – Dima Suba Jun 10 '13 at 12:21
  • Mmmh...would need to take some time to look into this. Maybe I find some time this evening. One quick thing that might help: I noticed that you use HTTPS only on the dashboard this might cause some iritations with the session Spring uses, as a first step try to make all pages require HTTPS and see if the problem persists. (On a sidenote at least the login should also be HTTPS, and I prefer to keep all pages access after login HTTPS too to keep the session data encrypted and a little more secure) – Carsten Jun 10 '13 at 13:05
  • Hi...yes, tried changing everything to https...no change in behavior unfortunately. Also, could you please clarify how I can access same object via session? Thanks so much! – Dima Suba Jun 11 '13 at 02:32

1 Answers1

30

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

Towfiqul Islam
  • 456
  • 6
  • 14
Carsten
  • 1,511
  • 2
  • 13
  • 24
  • Thanks a lot! So (am I understanding correctly?) - you're saying I should set SecurityContext object in the session as an attribute and then pull it from there after redirects instead of of pulling it from SecurityContextHolder? – Dima Suba Jun 11 '13 at 13:21
  • Well usually Spring Security should do this on it's own. depending on what parts of it you implemented yourself functionality might be broken. Try to find out whats happening with the securitycontext in debug mode and find the moment where the behaviour derivates from what is stated in the documentation. To shortcut this process: If you are populating the securityContext yourself you probably also have to attach it to the session. – Carsten Jun 11 '13 at 13:31
  • This really helped! Unfortunately can't vote your answer up, it requires "reputation" that I don't have :( – Dima Suba Jun 13 '13 at 03:33
  • So essentially, every time I use redirect now, I need to pull the user's data from Spring Security Context object, and then reassign the Authentication on the SecurityContext...isn't it weird that there's nothing written on it in Spring Security docs? Also, I'm not flipping between HTTP and HTTPS, I'm always in the HTTPS domain. – Dima Suba Jun 13 '13 at 03:36
  • If the answer solved your problem you can accept it as solution. Well usually this process takes place automatically but depending on the level of custom implementations that might change. – Carsten Jun 13 '13 at 07:06
  • 3
    In my app HttpSession session = request.getSession(true); sysout(session.getAttribute("SPRING_SECURITY_CONTEXT")); is != null but SecurityContextHolder.getContext().getAuthentication() is null. – Premier Jul 26 '13 at 14:25
  • Well, is this a question, a remark or just more information to add to the topic? If it is an question/request for help you should probably open up a new question (make sure it is distinct from this one in some way, so it is not marked as duplicate). Just send me a message with a link there since I don't check on the questions regularly right now. – Carsten Jul 30 '13 at 07:29