2

My corporate intranet application uses a pre-authentication scenario. It has two filters inserted before the SpringSecurity filter chain. The first is a filter provided by the Corporation. It handles all logins, passwords, etc. and if it recognizes the user, puts authentication data in the Principal in cookies. The second translates all this, creates UserDetails object and an Authentication token and places it in the SecurityContextHolder.

SecurityContextHolder.getContext().setAuthentication(token);
logger.debug("Auth token submitted");

My log confirms that this is happening:

2015-09-30 13:02:08,998 DEBUG c.a.v.c.s.MyPreauthFilter [http-bio-8081-exec-63] Auth token submitted

A few ms later, the Spring Security filter chain comes in and does the following:

2015-09-30 13:02:09,002 DEBUG o.s.s.w.FilterChainProxy [http-bio-8081-exec-63] /index.html at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2015-09-30 13:02:09,007 DEBUG o.s.s.w.FilterChainProxy [http-bio-8081-exec-63] /index.html at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2015-09-30 13:02:09,008 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository [http-bio-8081-exec-63] HttpSession returned null object for SPRING_SECURITY_CONTEXT
2015-09-30 13:02:09,008 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository [http-bio-8081-exec-63] No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@721c23ce. A new one will be created.

Basically, the HttpSessionSecurityContextRespository is invoked by the SecurityContextPersistenceFilter (part of the filter chain) and checking the SESSION for the security context, not finding one in the session, and replacing the context I just placed in the SecurityContextHolder, with a new empty one, resulting in authentication failure a few lines below.

2015-09-30 13:02:09,024 DEBUG o.s.s.w.a.ExceptionTranslationFilter [http-bio-8081-exec-63] Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied

Since the Spring docs don't mention the HttpSessionSecurityContextRespository, I figure I probably shouldn't mess with that.

Instead, I thought that maybe I could try inserting the second filter AFTER the Spring Security Filter chain, but that didn't help. The FilterSecurityInterceptor (11th item in the chain) refused to authenticate me, just as it did when my second filter was before it on the chain.

What DOES save the SecurityContext in the session and how may I defeat the behavior of the SecurityContextPersistenceFilter in wiping out the security context I have just set?

Steve Cohen
  • 4,679
  • 9
  • 51
  • 89

1 Answers1

0

I've developed a Workaround. It shouldn't be necessary, but it seems to work.

@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException 
{

...
    PreAuthenticatedAuthenticationToken token = ...


    logger.debug("Auth token placed in SecurityContext: \n" + token);
    SecurityContextHolder.getContext().setAuthentication(token);

    // make sure the session has a SecurityContext at this point
    ensureSessionHasSecurityContext(hreq);

    super.doFilter(request,response, chain);

    logger.debug("Auth token after rest of chain: \n" + SecurityContextHolder.getContext()
            .getAuthentication());

}

private void ensureSessionHasSecurityContext(HttpServletRequest hreq) {
    HttpSession session = hreq.getSession(false);
    Object securityContext = session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
    if (securityContext == null) {
        logger.debug("no SecurityContext found in session, inserting ours");
        session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
    }

}

Please debunk this solution if it appears problematical to you. But it is the only way I can think of to assure that the Filter Chain does not whack my new authentication, at time I want it to, just after my preauth filter has done its job, but before the Spring Filter Chain takes over.

Steve Cohen
  • 4,679
  • 9
  • 51
  • 89