【问题标题】:How to create a custom global exception handler for filters in Spring Security?如何在 Spring Security 中为过滤器创建自定义全局异常处理程序?
【发布时间】:2019-11-15 05:18:30
【问题描述】:

有没有办法自定义处理程序来处理 Spring Security 异常和 Spring Security 过滤器中的自定义异常?我需要一个带有错误信息的格式化响应发送到前端。

【问题讨论】:

标签: java spring-boot exception spring-security


【解决方案1】:

您可以通过添加过滤器来实现自定义全局异常处理程序:

@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();
    }  
}

发送到前端的错误信息将包含在 ErrorInfo 类中:

public class ErrorInfo {

    // some custom fields as you wish

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

正如您在上面看到的,通过添加@Order 注释和HIGHEST_PRECEDENCE 作为值,让过滤器在所有其他过滤器之前执行非常重要。如果有一些其他过滤器具有相同的顺序,则必须增加它们的顺序(例如,将 Ordered.HIGHEST_PRECEDENCE 替换为 Ordered.HIGHEST_PRECEDENCE + 1)以使其执行在我们的异常处理过滤器之后。

此外,您必须确保您的过滤器在 Spring Security 过滤器链之前执行。因此,您需要通过将 application.properties 中的 security.filter-order 属性设置为高于我们的 GlobalExceptionFilter:

security.filter-order=0

当我们的过滤器链中的某个地方发生异常时,该异常将被 GlobalExceptionFilter 捕获,然后创建一个包含错误信息的 ErrorInfo 对象并序列化它使用Jackson ObjectMapper。最后,响应以给定的 HTTP 状态发送到客户端。

【讨论】:

  • 谢谢,它有很大帮助。还有一个问题,为什么要将异常过滤器设置为最高级别?在我看来,它应该是最低的。我对订单感到困惑
  • 我认为异常过滤器应该是链中的最后一个。然后它可以捕获所有异常
  • 我也觉得这个名字令人困惑。如果你看一下这个整数常量的值,你会发现它的值是 Integer.MIN_VALUE。实际上,具有较低阶的过滤器比具有较高阶的过滤器具有更高的优先级。它们按升序“排序”。可能创建者给它起这个名字是为了强调更高的优先级(优先级),它赋予具有较低顺序值的 bean..
  • @wl.GIG 它必须排在所有其他过滤器之前,因为这是链中的第一个过滤器,然后它将请求转发到下一个过滤器,每个过滤器也将其转发到下一个过滤器。一个过滤器执行完毕后,控制流会返回给他之前的过滤器,所以最后的控制流会返回给链中的第一个过滤器。
  • 我明白了。谢谢
猜你喜欢
  • 2021-08-09
  • 2022-10-19
  • 1970-01-01
  • 1970-01-01
  • 2016-03-25
  • 2021-10-31
  • 2023-03-07
  • 2016-12-20
  • 2010-10-19
相关资源
最近更新 更多