We're using Spring Security to secure our Spring web application. In fact we're using a Spring Social authentication filter. It was not easy to get it working, but it works now and everything is great.
The only thing missing is that the user name doesn't appear in the Tomcat logs. In Tomcat, if I use good old fashioned BASIC authentication, the logged in user appears nicely in the logs. That is very helpful. I want to know which authorized user is doing certain things, for analytics etc.
I know that Tomcat logs the user based on httpServletRequest.getRemoteUser(). Spring stores user info as SecurityContextHolder.getSecurityContext().getPrincipal().
I looked around at the Spring documentation and it looks like I need to add the SecurityContextHolderAwareRequestFilter to the chain, which will wrap the HttpServletRequest and provide useful implementations of getSecurityContext() and other methods.
I tried to add that to my Java SecurityConfiguration class, like this:
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.addFilter(new SecurityContextHolderAwareRequestFilter())
but when I do that, I get an exception:
java.lang.NullPointerException
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
I can see clearly what is going on. At that line in SecurityContextHolderAwareRequestFilter, it is:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(requestFactory.create((HttpServletRequest)req, (HttpServletResponse) res), res);
}
Either the chain parameter is null (not likely) or the requestFactory member is null.
Looking at the code some more, it looks like the requestFactory member is created by calling afterPropertiesSet(). When is the right spot for making that call? Is this whole approach even the right approach?
Can anyone tell me what's the right way to do this? Surely there's some correct way to get the user name to show up in Tomcat logs?
Thanks