Spring Security:如何让/api/v1/login绕过JwtRequestFilter拦截
问题分析与解决方案
你遇到的核心问题是:自定义JwtRequestFilter的执行时机早于Spring Security的权限控制逻辑,或者过滤器内部未对/api/v1/login接口做放行处理,导致permitAll()配置未生效。以下是具体解决方法:
方案一:调整过滤器在Spring Security过滤链中的位置
不要将JwtRequestFilter直接注册到Servlet容器,而是通过Spring Security的配置指定其在过滤链中的位置,确保权限判断逻辑优先执行。
修改WebSecurityConfig代码:
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private JwtRequestFilter jwtRequestFilter; @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() // 先配置放行规则,优先匹配 .authorizeRequests() .antMatchers(HttpMethod.POST, "/api/v1/login").permitAll() // 其余接口需认证 .anyRequest().authenticated() .and() // 将Jwt过滤器添加到用户名密码认证过滤器之前 .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); } }
方案二:在JwtRequestFilter内部直接排除登录接口
如果过滤器是通过@Component+@Order直接注册到Servlet容器的,需在过滤器逻辑中主动跳过登录接口的校验:
修改JwtRequestFilter代码:
@Component public class JwtRequestFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 匹配登录接口,直接放行 String requestPath = request.getRequestURI(); String requestMethod = request.getMethod(); if ("/api/v1/login".equals(requestPath) && HttpMethod.POST.name().equals(requestMethod)) { filterChain.doFilter(request, response); return; } // 原有的JWT校验逻辑 String authorizationHeader = request.getHeader("Authorization"); if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) { throw new ServletException("Authorization header is missing"); } // ... 后续JWT解析、认证逻辑 filterChain.doFilter(request, response); } }
额外注意事项
- 路径匹配准确性:如果应用有上下文路径(如
/myapp/api/v1/login),需确保配置中的路径包含上下文路径,或使用antMatchers("/**/api/v1/login")这类通配规则。 - 规则顺序:
permitAll()的配置必须放在anyRequest().authenticated()之前,Spring Security会按配置顺序匹配规则,优先执行靠前的配置。
内容的提问来源于stack exchange,提问作者Hamza BOUSALIH
相关产品推荐
相关产品推荐

