Spring Security中AuthenticationEntryPoint无法识别原始AuthenticationException如何解决
该需求可以实现,你对异常被覆盖的原因判断完全正确,以下是两种可行的实现方案:
方案1:重写自定义PreAuthenticatedProcessingFilter的异常处理逻辑(最推荐)
该方案从根源阻断异常被覆盖的流程,适配所有接口场景,无需额外修改EntryPoint逻辑。AbstractPreAuthenticatedProcessingFilter 默认的认证失败处理逻辑会清空安全上下文后继续传递请求到后续过滤器,才会触发后续权限校验的异常覆盖。你可以重写unsuccessfulAuthentication方法,认证失败后直接调用你已实现的AuthenticationFailureHandler返回响应,终止过滤器链的传递:
@Override protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { SecurityContextHolder.clearContext(); // 直接调用已有的AuthenticationFailureHandler处理原始异常,返回对应响应 myAuthenticationFailureHandler.onAuthenticationFailure(request, response, failed); // 无需调用父类实现,避免请求继续向后传递 }
方案2:请求上下文存储原始异常,EntryPoint优先读取
如果需要保留过滤器默认的请求向后传递逻辑,可以通过请求属性透传原始异常:
- 重写自定义过滤器的
unsuccessfulAuthentication方法,将原始异常存入请求属性:
@Override protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { // 存入原始异常到请求属性,仅当前请求内有效 request.setAttribute("original_authentication_exception", failed); // 调用父类方法保留原有逻辑 super.unsuccessfulAuthentication(request, response, failed); }
- 在
MyAuthenticationEntryPoint的commence方法中优先读取原始异常做分支判断:
@Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { // 优先读取透传的原始认证异常 AuthenticationException originalException = (AuthenticationException) request.getAttribute("original_authentication_exception"); AuthenticationException usedException = originalException != null ? originalException : authException; // 原有异常分支判断逻辑,将入参的authException替换为usedException即可 if (usedException instanceof UsernameNotFoundException) { // 对应跳转逻辑 } else if (usedException instanceof CredentialsExpiredException) { // 对应跳转逻辑 } else if (usedException instanceof LockedException) { // 对应跳转逻辑 } // 其余异常处理逻辑 }
注:你当前使用的是STATELESS无状态会话策略,请求属性仅在单次请求内生效,不会有线程安全或数据串扰问题。
内容的提问来源于stack exchange,提问作者富本 悠介
相关产品推荐
相关产品推荐

