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?