How to create a custom global exception handler for filters in Spring Security?

wl.GIG :

Is there a way to custom a handler to deal with Spring Security exception and custom exception in Spring Security filters? I need a formatted response with error infomation sent to front end.

Marko Previsic :

You can implement a custom global exception handler by adding a filter:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class GlobalExceptionFilter extends OncePerRequestFilter {

    private final ObjectMapper mapper = new ObjectMapper();

    @Override
    protected void doFilterInternal(HttpServletRequest request, 
        HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    try {
        filterChain.doFilter(request, response);
    } catch (Exception ex) {
        mapper.writeValue(response.getWriter(), new ErrorInfo("something bad happened"));
        response.setContentType(MediaType.APPLICATION_JSON);
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        response.getWriter().close();
        response.getWriter().flush();
    }  
}

The error information sent to the frontend would be contained in the ErrorInfo class:

public class ErrorInfo {

    // some custom fields as you wish

    public ErrorInfo(String error) {
        ...
    }
}

As you can see above, it's important to let the filter execute before all other filters by adding the @Order annotation with HIGHEST_PRECEDENCE as value. If there are some other filters with the same order, you have to increase their order (for example by replacing Ordered.HIGHEST_PRECEDENCE with Ordered.HIGHEST_PRECEDENCE + 1) to make them execute after our exception handling filter.

Also, you have to ensure that your filter gets executed before the Spring Security filter chain. Thus, you need to change the order of the Spring Security filter-chain by setting the security.filter-order property in application.properties to some value higher than the order of our GlobalExceptionFilter:

security.filter-order=0

When an exception happens somewhere in our filter-chain, the exception will be caught by the GlobalExceptionFilter which in turn creates an ErrorInfo object containing information about the error and serializes it using a Jackson ObjectMapper. Finally, the response is sent to the client with a given HTTP status.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=145543&siteId=1