You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring认证过滤器抛出的异常错误信息不符合预期如何解决?

问题核心原因

@ControllerAdvice 仅能捕获Spring MVC Controller层抛出的异常,自定义身份认证过滤器的执行顺序在DispatcherServlet之前,你在过滤器中抛出的IrrecoverableAuthException会直接被Spring Security内置的异常处理过滤器捕获,走默认的认证失败逻辑,根本无法触发你定义的全局异常处理器,所以会返回系统默认的「Full authentication access is required to access this resource」提示。

可行解决办法
  • 方案1:在过滤器内直接捕获异常手动返回响应

    这是最直接的方案,不需要修改其他配置,只需调整你的过滤器代码,对认证逻辑做异常捕获,匹配到自定义认证异常时直接构造你需要的返回体写入响应即可,代码示例:

    @Slf4j
    // 建议去掉@Component注解,避免过滤器被Spring Boot自动注册到全局过滤链导致重复执行
    public class TokenValidationFilter extends OncePerRequestFilter {
    
      @Autowired
      private TokenValidationHelper tokenValidationHelper;
      // 注入ObjectMapper用于序列化错误响应
      @Autowired
      private ObjectMapper objectMapper;
    
      @Override
      protected void doFilterInternal(HttpServletRequest servletRequest, 
                HttpServletResponse servletResponse,
                FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest httpRequest = (HttpServletRequest)servletRequest;
        HttpServletResponse httpResponse = (HttpServletResponse)servletResponse;
        MultiReadRequestWrapper request = new MultiReadRequestWrapper(httpRequest);
        SecurityContext context = SecurityContextHolder.getContext();
        // check if already authenticated
        if (context.getAuthentication() == null) {
          try {
            Authentication authentication = 
              tokenValidationHelper.validateAndAuthenticate(request);
            context.setAuthentication(authentication);
          } catch (IrrecoverableAuthException e) {
            // 手动构造错误响应
            httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            httpResponse.setContentType("application/json;charset=UTF-8");
            RegistrationErrorResponse errorResponse = getErrorResponse(e, Category.Error, e.getMessage());
            httpResponse.getWriter().write(objectMapper.writeValueAsString(errorResponse));
            // 直接返回,不再继续走后续过滤链
            return;
          }
        }
        filterChain.doFilter(request, httpResponse);
      }
    
      // 这里把你异常处理器里的getErrorResponse逻辑挪过来,或者抽成公共工具方法调用即可
      private RegistrationErrorResponse getErrorResponse(IrrecoverableAuthException e, Category error, String message) {
        // 你的错误响应构造逻辑
      }
    }
    

    调整后记得在Spring Security配置类中,手动将该过滤器添加到UsernamePasswordAuthenticationFilter之前执行即可。

  • 方案2:自定义Spring Security认证入口点统一处理

    如果你希望所有认证相关异常统一走公共处理逻辑,可以自定义AuthenticationEntryPoint,在里面实现错误响应构造逻辑,然后在Spring Security配置中把自定义入口点注册进去,所有Spring Security捕获到的认证异常都会走这个入口点的处理逻辑,和你的全局异常处理器效果一致。

其他注意事项

你贴出的异常处理器代码存在语法错误,getErrorResponse(exception , Category.Error exception.getMessage()) 两个参数之间缺少逗号,修正为getErrorResponse(exception, Category.Error, exception.getMessage())即可正常编译。


内容的提问来源于stack exchange,提问作者lwjmexppgkjpph

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 19:54:06