1

I am using spring-session with hazelcast and spring-security. I am facing an issue where spring security fails to load security context from httpsession. During authentication I can see security context is set to session in following code:

if (contextChanged(context)||  httpSession.getAttribute(springSecurityContextKey) == null) {
  httpSession.setAttribute(springSecurityContextKey, context);
  if (logger.isDebugEnabled()) {
    logger.debug("SecurityContext '" + context
                + "' stored to HttpSession: '" + httpSession);
    }
}

But after authentication when spring redirects to target url, it fails to get Security Context from session in following code:

Object contextFromSession = httpSession.getAttribute(springSecurityContextKey);

if (contextFromSession == null) {

  if (debug) {
    logger.debug("HttpSession returned null object for SPRING_SECURITY_CONTEXT");
  }
  return null;
}

Any idea what could be wrong here? Security debug log-

w.a.s.SessionFixationProtectionStrategy : Started new session: 2192be54-aee1-4249-98ba-01a65a401830
c.i.i.w.s.LoggingSecurityEventListener   : event=SessionFixationProtectionEvent username=cgrant remoteAddress=0:0:0:0:0:0:0:1 sessionId=c7363d39-28ff-44e3-83a9-d463f2f371e5
w.a.UsernamePasswordAuthenticationFilter : Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@5e87c6c5: Principal: org.springframework.security.core.userdetails.
c.i.i.w.s.LoggingSecurityEventListener   : event=InteractiveAuthenticationSuccessEvent username=cgrant remoteAddress=0:0:0:0:0:0:0:1 sessionId=c7363d39-28ff-44e3-83a9-d463f2f371e5
RequestAwareAuthenticationSuccessHandler : Using default Url: /
o.s.s.web.DefaultRedirectStrategy        : Redirecting to '/myapp/'
w.c.HttpSessionSecurityContextRepository : SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@5e87c6c5: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@5e87c6c5: Principal: org.springframework.security.core.userdetails.User@fb03e089: Username: cgrant; .......... stored to HttpSession: 'org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper@5d2baa59
s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
o.s.s.w.s.HttpSessionEventPublisher      : Publishing event: org.springframework.security.web.session.HttpSessionCreatedEvent[source=org.springframework.session.web.http.ExpiringSessionHttpSession@287a471f]
.....
.....
o.s.security.web.FilterChainProxy        : / at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
o.s.security.web.FilterChainProxy        : / at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper@8d3c315. A new one will be created.
o.s.security.web.FilterChainProxy        : / at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@57f4e063
o.s.security.web.FilterChainProxy        : / at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/'; against '/logout'
o.s.security.web.FilterChainProxy        : / at position 5 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /' doesn't match 'POST /login/auth
o.s.security.web.FilterChainProxy        : / at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
o.s.security.web.FilterChainProxy        : / at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
o.s.security.web.FilterChainProxy        : / at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
o.s.s.w.a.AnonymousAuthenticationFilter  : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@6fa843a8: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffd3270: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 2192be54-aee1-4249-98ba-01a65a401830; Granted Authorities: ROLE_ANONYMOUS'
o.s.security.web.FilterChainProxy        : / at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
o.s.security.web.FilterChainProxy        : / at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
o.s.security.web.FilterChainProxy        : / at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
.....
.....
o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /; Attributes: [authenticated]
o.s.s.w.a.i.FilterSecurityInterceptor    : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@6fa843a8: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffd3270: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 2192be54-aee1-4249-98ba-01a65a401830; Granted Authorities: ROLE_ANONYMOUS
o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@1023c8f1, returned: -1
o.s.s.w.a.ExceptionTranslationFilter     : Access is denied (user is anonymous); redirecting to authentication entry point
Dylan
  • 2,161
  • 2
  • 27
  • 51
Husain
  • 41
  • 1
  • 6

3 Answers3

2

After successful authentication, Spring Security destroys the previous session and creates a new one with authentication set to true.

Therefore, Context Object you had put into Session before authentication will not be available after authentication because previous session would be destroyed.

This Strategy is known as Session Fixation. You can Read Here more about this.

Therefore, If you want to get Context after authentication, then use:

Object contextObject = org.springframework.security.core.context.SecurityContextHolder.getContext();

Spring Security Chain Filter in web.xml:

    <filter-mapping>
      <filter-name>springSecurityFilterChain</filter-name>
      <url-pattern>/*</url-pattern>
      <dispatcher>REQUEST</dispatcher>
      <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
gschambial
  • 1,383
  • 2
  • 11
  • 22
  • 1
    My application works fine with Spring security, this problem occurs when I am adding spring-session to my application. To add spring-session I am doing two things- – Husain Oct 21 '16 at 12:40
  • @THusain There is nothing like `spring-session`, there is only `http-session` in a Java Web Application. – gschambial Oct 21 '16 at 12:42
  • 1
    I am not doing anything with SecurityContext, the code I pasted is from spring-security framework. When a user is successfully authenticated the framework itslf placing the SecurityContext object to session. When a new request is made from same user the SecurityContext is populated from session. In my case after authentication spring-security places the SecurityContext in session and redirects to target url, again when redirect request comes to spring-security It did not find SecurityContext object in session even the session id is same. Dont know what is going wrong. – Husain Oct 21 '16 at 13:01
  • I understood, what you are saying. in Spring `SessionFixationProtectionStrategy` by default `migrateSession` attribute is set to true. It means all the attributes of previous session will be copied into the New Session. – gschambial Oct 21 '16 at 13:09
  • @THusain Let me study a bit about Why New session is not getting the session attribute from previous session and get back to you. – gschambial Oct 21 '16 at 13:13
  • @gcchambial spring 4.0.1 – Husain Oct 21 '16 at 13:55
  • @THusain Can you check my answer and confirm if you have the similar setting of your `springSecurityChainFilter` ? – gschambial Oct 21 '16 at 14:00
  • I dont have web.xml, I am using java configuration, is there a way to add this filter without web.xml? – Husain Oct 21 '16 at 14:05
2

I found the actual cause of this issue. I was using Spring-session-1.2.2 and hazelcast-3.5.4. Spring-session was failing to save session after migration. I don't know if it is hazelcast issue or spring-session issue. Just for testing purpose i used MapSessionRepository with @EnableSpringHttpSession and everything worked fine. It was painful experience while debugging spring-session library, Based on my experience I'll suggest before using any storage for session replication first test with MapSessionRepository this will ensure your application configuration works with spring-session, later moved to use third party session repository.

Husain
  • 41
  • 1
  • 6
0

for Chrome you can see the cookie settings at Settings --> Content Settings --> Cookies --> Allow sites to save and read cookie data (recommended)