Spring Security antMatcher配置失效:无法排除指定URL问题求助
解决方案
问题根源分析
你的配置存在两个核心问题:
- 路径匹配错误:在
HttpSecurity的authorizeRequests中,你使用了.antMatchers(HttpMethod.POST, "/icici/pay"),但由于之前通过.antMatcher("/v1/btob/**")限定了该HttpSecurity实例仅处理/v1/btob/开头的请求,这里的短路径无法匹配到/v1/btob/icici/pay,导致该URL被anyRequest().authenticated()规则覆盖,过滤器依然会执行。 - 冗余配置冲突:你重复配置了
csrf().disable()和sessionManagement,可能导致配置逻辑混乱,影响规则生效。
方案1:通过HttpSecurity允许访问并跳过认证(保留过滤器链)
如果你只是想让该URL无需认证但仍经过Spring Security过滤器链,可修改HttpSecurity配置,修正路径匹配并合并冗余配置:
@Override public void configure(HttpSecurity http) throws Exception { http .csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .cors() .and() .antMatcher("/v1/btob/**") .httpBasic() .and() .authorizeRequests() // 使用完整路径匹配目标URL .antMatchers(HttpMethod.POST, "/v1/btob/icici/pay").permitAll() .anyRequest().authenticated() .and() .addFilterBefore(btoBFilter, UsernamePasswordAuthenticationFilter.class); }
方案2:通过WebSecurity完全跳过所有Spring Security过滤器
如果你想让该URL完全绕过Spring Security的整个过滤器链(包括自定义的btoBFilter),需确保WebSecurity的路径配置正确,同时简化HttpSecurity配置:
1. 修正WebSecurity配置
@Override public void configure(WebSecurity web) { // 完全跳过指定路径的所有Spring Security处理逻辑 web.ignoring() .antMatchers(HttpMethod.POST, "/v1/btob/icici/pay"); }
2. 简化HttpSecurity配置(合并冗余项)
@Override public void configure(HttpSecurity http) throws Exception { http .csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .cors() .and() .antMatcher("/v1/btob/**") .httpBasic() .and() .authorizeRequests() .anyRequest().authenticated() .and() .addFilterBefore(btoBFilter, UsernamePasswordAuthenticationFilter.class); }
特殊情况处理:自定义过滤器独立于Spring Security链
如果你的btoBFilter是通过@WebFilter等方式直接注册到Servlet容器的(而非通过Spring Security的addFilterBefore),那么WebSecurity.ignoring()不会影响它。此时需要在过滤器内部添加路径判断,跳过目标URL:
public class BtoBFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String requestPath = request.getRequestURI(); HttpMethod requestMethod = HttpMethod.valueOf(request.getMethod()); // 匹配到目标URL则直接跳过过滤逻辑 if (HttpMethod.POST.equals(requestMethod) && "/v1/btob/icici/pay".equals(requestPath)) { filterChain.doFilter(request, response); return; } // 原有过滤逻辑 // ... filterChain.doFilter(request, response); } }
内容的提问来源于stack exchange,提问作者Himanshu Ranjan
相关产品推荐
相关产品推荐

