Spring SecurityContext returns null authentication on error pages

I am trying to write a custom error page for errors such as 403 (access denied) and 500 (internal server error). They will be displayed from the Velocity template and all messages will be translated using the user locale. Authentication and local resolution work fine in the application.

I set the location in web.xml to be the desired page, and in webmvc-context.xml. I added a request controller to the view through.

The problem I came across is that SecurityContextHolder.getContext (). getAuthentication () returns null in the view of the error page. Looking at the magazine, I saw:

06.10 14:42:26 DEBUG - context.HttpSessionSecurityContextRepository(HttpSessionSecurityContextRepository.java:351) - - SecurityContext stored to HttpSession: ' org.springframework.security.core.context.SecurityContextImpl@ec e7b0b7: Authentication: ... 06.10 14:42:26 DEBUG - context.SecurityContextPersistenceFilter(SecurityContextPersistenceFilter.java:89) - - SecurityContextHolder now cleared, as request processing completed 06.10 14:42:26 DEBUG - servlet.DispatcherServlet(DispatcherServlet.java:691) - - DispatcherServlet with name 'foo' processing GET request for [/foo/app/error/403.html] 

Thus, either Spring or Tomcat is redirected to the error page, and the request-request is completed, so the context is cleared. And the new β€œrequest” is not subject to Spring security filters, which does not restore the context.

The normal method does not work, but it seems that the authentication information is somewhere in the session, also because AbstractTemplateView registers the following:

 Exposing session attribute 'SPRING_SECURITY_CONTEXT' with value [ org.springframework.security.core.context.SecurityContextImpl@ed fbd958: Authentication: org.springframework.security .web.authentication.preauth.PreAuthenticatedAuthenticationToken@ edfbd958... 

How to get it so that both normal and erroneous pages act the same?

+7
source share
2 answers

The problem you are facing is that the ExceptionTranslationFilter , which throws the exceptions to the error pages, precedes the SecurityContextPersistenceFilter , which pulls the authentication from the SecurityContextRepository and puts it in the SecurityContextHolder . When the request ends, the SecurityContextPersistenceFilter outputs information from the SecurityContextHolder .

The reason it clears the SecurityContextHolder is because the SecurityContextHolder usually a local thread, and if the servlet container needs to reuse the thread (most do), they might accidentally pass these credentials to someone else.

Typically, an ExceptionTranslationFilter is the most external filter to avoid the risk of throwing any exceptions.

It is best to write a custom ExceptionTranslationFilter that accepts a SecurityContextRepository (often an HTTP session, as you mentioned), and provides access to Authentication through a SecurityContextRepository rather than a SecurityContextHolder in mind that Authentication will still be empty if the user does not log in.

+5
source

The problem may be that springSecurityFilterChain does not intercept ERRORS. Try changing your mapping in web.xml to be

 <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping> 
+5
source

All Articles