添加Spring Security过滤器后Rest API无返回结果问题排查
问题原因与解决方案
核心问题是你的JwtRequestFilter仅做了请求放行,没有完成Spring Security的认证上下文注入,导致Spring Security认为请求未通过认证——即便返回200状态码,实际请求也没有正常流转到控制器执行。同时JwtAuthenticationEntryPoint的逻辑不完整,无法覆盖所有未认证场景。
1. 修复JwtRequestFilter,添加认证逻辑
修改过滤器,解析Bearer Token并将认证信息注入Spring Security上下文:
@Component public class JwtRequestFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { // 提取Authorization头中的Bearer Token String authHeader = request.getHeader("Authorization"); String token = null; if (authHeader != null && authHeader.startsWith("Bearer ")) { token = authHeader.substring(7); // 去除"Bearer "前缀 } // 如果Token存在且当前上下文未认证 if (token != null && SecurityContextHolder.getContext().getAuthentication() == null) { // 此处替换为真实的Token校验逻辑:验证签名、过期时间、解析用户信息等 // 示例:模拟已通过认证的用户 UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( "authenticatedUser", // 实际从Token解析用户名 null, Collections.emptyList() // 实际从Token解析用户权限 ); // 将认证信息存入上下文,Spring Security会认可该请求已认证 SecurityContextHolder.getContext().setAuthentication(authToken); } // 继续执行后续过滤器链,请求将流转到控制器 chain.doFilter(request, response); } }
2. 修复JwtAuthenticationEntryPoint,覆盖所有未认证场景
原来的逻辑仅处理Token为空的情况,修改为所有认证失败场景都返回401:
@Component public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { // 所有未认证请求统一返回401 response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized: " + authException.getMessage()); } }
3. 验证逻辑说明
- 当你传入有效Token时,过滤器会将认证信息注入
SecurityContextHolder,Spring Security的anyRequest().authenticated()规则会判定请求已通过认证,允许请求到达控制器,正常返回字符串列表。 - 当Token为空或无效时,
SecurityContextHolder中无认证信息,Spring Security会调用JwtAuthenticationEntryPoint返回401,符合预期。
内容的提问来源于stack exchange,提问作者noob555
相关产品推荐
相关产品推荐

