Spring Security放行请求被JwtAuthenticationFilter拦截问题求助
问题分析与解决方案
问题根源
你的JwtAuthenticationFilter作为自定义OncePerRequestFilter,执行优先级高于Spring Security的授权校验逻辑(FilterSecurityInterceptor)。当前过滤器仅硬编码放行/ss023/user/register,其余所有请求都会强制进入JWT校验流程并返回未授权,导致Security配置中permitAll()的其他路径完全失效。
解决方案:统一管理放行路径
修改JwtAuthenticationFilter,使用路径匹配器统一匹配所有无需认证的路径,和Security配置保持一致:
public class JwtAuthenticationFilter extends OncePerRequestFilter { private final JwtTokenService jwtTokenService; private final UserDetailsService userDetailsService; // 同步Security配置中的放行路径,支持通配符 private static final List<String> PERMIT_ALL_PATHS = Arrays.asList( "/ss023/user/register", "/ss023/user/getStringTwo", "/css/**", "/register", "/login" ); private final AntPathMatcher pathMatcher = new AntPathMatcher(); // 补全构造方法 public JwtAuthenticationFilter(JwtTokenService jwtTokenService, UserDetailsService userDetailsService) { this.jwtTokenService = jwtTokenService; this.userDetailsService = userDetailsService; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String path = request.getRequestURI(); // 检查当前路径是否属于放行列表 boolean isPermitted = PERMIT_ALL_PATHS.stream() .anyMatch(permitPath -> pathMatcher.match(permitPath, path)); if (isPermitted) { // 直接放行,跳过JWT校验 filterChain.doFilter(request, response); return; } // 原有JWT校验逻辑保持不变 String authToken = jwtTokenService.getToken(request); if (null != authToken) { String username = jwtTokenService.getUsernameFromToken(authToken); if (null != username) { UserDetails userDetails = userDetailsService.loadUserByUsername(username); if (jwtTokenService.validateToken(authToken, userDetails)) { Authentication authentication = new UsernamePasswordAuthenticationToken( userDetails, null, userDetails.getAuthorities() ); SecurityContextHolder.getContext().setAuthentication(authentication); filterChain.doFilter(request, response); } else { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("application/json"); response.getWriter().write("{\"error\":\"Bearer Token Expired\"}"); } } else { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("application/json"); response.getWriter().write("{\"error\":\"Wrong bearer token\"}"); } } else { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("application/json"); response.getWriter().write("{\"error\":\"No bearer token\"}"); } } }
关键注意事项
- 使用
AntPathMatcher支持通配符路径(如/css/**),避免直接用equals导致通配符失效; - 必须放行
/login路径,否则自定义登录过滤器CustomUsernamePasswordAuthenticationFilter无法处理登录请求; - 放行路径需和Security配置中的
requestMatchers保持同步,避免出现配置不一致的情况。
内容的提问来源于stack exchange,提问作者AM0007
相关产品推荐
相关产品推荐

