Spring FilterChain + Security: log request with user or not

Viewed 568

I have a Spring web-mvc REST-service with several initializers.

WebAppInitializer.java

@Order(1)
public class MyFiltersInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) {
        FilterRegistration.Dynamic registration = servletContext.addFilter("myRequestFilter", DelegatingFilterProxy.class);
        // register other filters and DispatcherServlet
    }
}

SecurityWebAppInitializer.java

@Order(2)
public class MySecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

    @Override
    protected Set<SessionTrackingMode> getSessionTrackingModes() {
        return EnumSet.of(SessionTrackingMode.COOKIE, SessionTrackingMode.URL);
    }
}

As you can see, SecurityFilterChain is being added after all custom request filters. What I need to do is to log every request, and include User to log, if request is authorized

Something like MyRequestFilter.java:

@Slf4j
public class RequestFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(final HttpServletRequest request,
                                    final HttpServletResponse response,
                                    final FilterChain filterChain) throws ServletException, IOException {
           MyUser user = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); //no auth yet
           log.debug("request {} start, user {}", request, user); 
           filterChain.doFilter(request, response); //may return 401 or 403, what also need to be logged
           log.debug("request {} end with response {}", request, response);
   }

There is an idea to add an LogBodyHolder, which keeps log body until SecurityChain is passed completely, and then call log.debug. But is there any pretty way to solve this problem?

1 Answers

You can just create a Spring Bean that extends the class AbstractRequestLoggingFilter which is provided by Spring and then override the beforeRequest() and afterRequest() methods to add your logs as you wish.

Related