1

I have a real nice application listener registered as seen below.

@Component
public class MyLogger implements ApplicationListener {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        // not doing anything here
        // Check out the 'RequestHandledEvent' below though.
    }

    @EventListener(RequestHandledEvent.class)
    public void onApplicationEvent(RequestHandledEvent event) {
        // I'd like to get the HttpServletRequest that was just handled.
        // Furthermore, I'd really like to get the userPrincipal that was
        // on the request, so that I can know made the request

        // it seems I can do this
        // but the principal seems to already have been cleared.
        // is there a more straightforward way to get the request?
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

}

I feel like I should be able to do something like

event.getRequest()

But I haven't found a successful way to do so.

Long story short, I'd like like ONE PLACE in my application that I can get at the request that came in, and the principal that was on that request, so that I can do some logging, etc.

Should I be looking at a different application event maybe?

1 Answer 1

2

You can get request with proper security principal by registering servlet filter like:

@Component
public static class RequestLoggingFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        final Principal userPrincipal = request.getUserPrincipal();
        // ...do what you want with principal and request info here
        filterChain.doFilter(request, response);
    }
}

To control order of fiters in filter chain you can either annotate your filter class with @Order annotation or register filter like this:

@Bean
public FilterRegistrationBean filterRegistrationBean() {
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    RequestLoggingFilter filter = new RequestLoggingFilter();
    registrationBean.setFilter(flter);
    registrationBean.setOrder(Ordered.LOWEST_PRECEDENCE);
    return registrationBean;
}
Sign up to request clarification or add additional context in comments.

4 Comments

How do I made sure this filter is the LAST thing that handles the request before the response is sent back to the client? Is there ordering configuration that I can read about?
Added info about filters ordering.
Okay. This seems to work pretty good. Problem is, this filter doesn't get hit if something happens up in Spring Security's chain (example - bad token gets passed in). I'm trying to find a single spot to be able to handle all these workflows, and find a single point of exit for my application where I'm able to log.
Lastly. This filter gets hit BEFORE the controller is called. Is there a filter/auditor/event listener I can use to get the request and response AFTER a controller has done it's thing?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.