Spring Security 6自定义过滤器未按指定URL路径生效,反而作用于所有URL(含/login)
兄弟,我太懂你这个糟心的情况了!之前在项目里也踩过Spring Security过滤器路径匹配的坑,明明只想让自定义过滤器管/api相关的路径,结果连/login都被拦截了,简直头大。咱们先捋清楚问题根源,再给你搞定它!
首先得明确:Spring Security里如果直接把自定义过滤器加到SecurityFilterChain里,默认是对所有请求生效的,除非你明确给它划定作用范围。结合你的描述,大概率是没给过滤器所在的FilterChain指定匹配路径,或者多个FilterChain的优先级/范围配置冲突了。
给你两个最靠谱的解决方案,按需选:
方案一:给FilterChain绑定专属路径(推荐)
这个方法最优雅,直接让整个FilterChain只处理你指定的/api开头的请求,自然过滤器也不会碰/login这类路径。你可以这么改你的配置:
@Configuration @EnableWebSecurity @EnableMethodSecurity public class SLWebConfig{ // 处理API路径的FilterChain,优先级设为1(值越小优先级越高) @Bean @Order(1) public SecurityFilterChain apiSecurityFilterChain(HttpSecurity http) throws Exception { http // 关键!指定这个FilterChain只处理这些路径 .securityMatcher("/api/**", "/api/v1/**") // 添加你的自定义过滤器,比如放在用户名密码认证过滤器之前 .addFilterBefore(new SecFilters(), UsernamePasswordAuthenticationFilter.class) // 配置API路径的授权规则 .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() ); return http.build(); } // 单独处理登录的FilterChain,优先级设为2 @Bean @Order(2) public SecurityFilterChain loginSecurityFilterChain(HttpSecurity http) throws Exception { http // 明确这个FilterChain只处理/login路径 .securityMatcher("/login") // 登录路径允许所有人访问 .authorizeHttpRequests(auth -> auth .anyRequest().permitAll() ) // 这里放你的登录相关配置,比如表单登录、OAuth2登录等 .formLogin(form -> form .loginProcessingUrl("/login") .permitAll() ); return http.build(); } }
这么配置后,两个FilterChain各司其职:Order(1)的只管/api开头的请求,自定义过滤器只会在这些请求里生效;Order(2)的专门处理/login,完全不会被自定义过滤器干扰。
方案二:在过滤器内部判断路径(应急用)
如果暂时不想改FilterChain的结构,也可以在你的SecFilters过滤器里自己判断请求路径,遇到/login直接放行:
public class SecFilters extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String requestUri = request.getRequestURI(); // 如果是登录路径,直接跳过过滤逻辑 if ("/login".equals(requestUri)) { filterChain.doFilter(request, response); return; } // 这里写你的自定义过滤逻辑 // ... 比如校验token、权限等 // 执行完后放行 filterChain.doFilter(request, response); } }
不过这个方法不如方案一优雅,毕竟硬编码路径不够灵活,后续路径变更还要改过滤器代码,优先推荐方案一。
最后再提醒你注意Order的优先级:Order值越小,FilterChain越先执行。所以如果你的登录FilterChain Order值比API的大,就会让API的FilterChain先处理请求——但只要给每个FilterChain都加上securityMatcher,就不会出现跨路径拦截的问题啦!
备注:内容来源于stack exchange,提问作者RituV

