Spring Security 6中InvalidBearerTokenException异常处理问题解决
解决Spring Boot 3 + Spring Security 6中InvalidBearerTokenException异常处理失效问题
问题根源
Spring Security的认证异常(包括InvalidBearerTokenException)是在Filter链阶段抛出的,而@ExceptionHandler注解的处理器仅在DispatcherServlet处理请求的阶段生效。这类Filter层的异常根本无法到达Controller层,因此你的自定义@ExceptionHandler无法捕获到它们。
解决方案
通过自定义AuthenticationEntryPoint来处理Filter链中的认证失败异常,直接在Filter层返回自定义错误响应,无需经过DispatcherServlet。
1. 实现自定义AuthenticationEntryPoint
创建一个类实现AuthenticationEntryPoint接口,重写commence方法来构建并返回自定义错误信息:
@Component public class CustomAuthEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { // 构建自定义错误对象 Error error = new Error() .errorCode(Error.ErrorCodeEnum.INVALID_TOKEN) .errorDescription(authException.getMessage()); // 设置响应状态和格式 response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.setContentType(MediaType.APPLICATION_JSON_VALUE); // 将错误对象序列化为JSON写入响应流 ObjectMapper objectMapper = new ObjectMapper(); objectMapper.writeValue(response.getOutputStream(), error); } }
2. 修改SecurityFilterChain配置
将自定义的AuthenticationEntryPoint配置到SecurityFilterChain中,替换默认的异常处理逻辑:
@Bean public SecurityFilterChain filterChain(HttpSecurity http, CustomAuthEntryPoint customAuthEntryPoint) throws Exception { http.csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(authorize -> authorize .requestMatchers("/v1/**").permitAll() // 补全权限规则,允许/v1路径无需认证 .anyRequest().authenticated()) .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())) .exceptionHandling(ex -> ex .authenticationEntryPoint(customAuthEntryPoint) // 配置自定义认证异常处理器 // 可选:自定义授权失败(无权限)的处理逻辑 .accessDeniedHandler((req, res, ex) -> { res.setStatus(HttpStatus.FORBIDDEN.value()); res.setContentType(MediaType.APPLICATION_JSON_VALUE); Error error = new Error().errorCode(Error.ErrorCodeEnum.ACCESS_DENIED).errorDescription(ex.getMessage()); new ObjectMapper().writeValue(res.getOutputStream(), error); })); return http.build(); }
3. 关于原有@ExceptionHandler的说明
你定义的@ExceptionHandler可以保留,用于捕获Controller层手动抛出的AuthenticationException子类异常,但无法处理Filter链阶段的认证异常。
内容的提问来源于stack exchange,提问作者user1428716
相关产品推荐
相关产品推荐

