Spring Boot 3中如何为特定端点配置专属安全过滤器
解决Spring Boot3/Spring Security6中过滤器按路径触发的问题
问题根源
你当前的配置把Filter1和Filter2直接添加到了全局的SecurityFilterChain中,所以所有请求都会经过这两个过滤器,不管请求路径是什么。另外注意你代码里的拼写错误:/endpoin3/**应该是/endpoint3/**,这个错误会导致路径匹配失效。
两种可行解决方案
方案一:在过滤器内部判断请求路径
直接修改过滤器类,在doFilter方法里判断请求路径,仅在目标路径下执行过滤器逻辑,否则直接放行。
Filter1.java:
public class Filter1 implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; String requestURI = httpRequest.getRequestURI(); // 仅在请求路径匹配/endpoint1/**时执行过滤器逻辑 if (requestURI.startsWith("/endpoint1/")) { // 这里写你的Filter1业务逻辑 System.out.println("Filter1 triggered for " + requestURI); } // 放行请求到后续过滤器或控制器 chain.doFilter(request, response); } }
Filter2.java同理:
public class Filter2 implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; String requestURI = httpRequest.getRequestURI(); if (requestURI.startsWith("/endpoint2/")) { // 这里写你的Filter2业务逻辑 System.out.println("Filter2 triggered for " + requestURI); } chain.doFilter(request, response); } }
修正拼写错误后,保留你最初的SecurityFilterChain配置即可,不需要额外修改链的结构。
方案二:创建多个带@Order的SecurityFilterChain
Spring Security6支持通过securityMatcher为不同路径配置独立的安全链,每个链只处理匹配的请求,并可单独添加对应的过滤器。注意要给每个链添加@Order注解,确保请求按顺序匹配到正确的链。
// 处理/endpoint1/**的安全链,优先级最高 @Bean @Order(1) public SecurityFilterChain endpoint1FilterChain(HttpSecurity http) throws Exception { http .securityMatcher("/endpoint1/**") .csrf(csrf -> csrf.disable()) .cors(cors -> cors.disable()) .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .addFilterBefore(new Filter1(), UsernamePasswordAuthenticationFilter.class); return http.build(); } // 处理/endpoint2/**的安全链,优先级次之 @Bean @Order(2) public SecurityFilterChain endpoint2FilterChain(HttpSecurity http) throws Exception { http .securityMatcher("/endpoint2/**") .csrf(csrf -> csrf.disable()) .cors(cors -> cors.disable()) .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .addFilterBefore(new Filter2(), UsernamePasswordAuthenticationFilter.class); return http.build(); } // 处理其他路径(/endpoint3/**、静态资源、error等)的安全链,优先级最低 @Bean @Order(3) public SecurityFilterChain otherFilterChain(HttpSecurity http) throws Exception { http .securityMatcher("/endpoint3/**", "/error/**", PathRequest.toStaticResources().atCommonLocations()) .csrf(csrf -> csrf.disable()) .cors(cors -> cors.disable()) .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); // 这里不添加任何自定义过滤器,确保/endpoint3等路径不会触发Filter1/Filter2 return http.build(); }
为什么之前多链配置失效?
大概率是没有正确使用securityMatcher指定链的匹配路径,或者@Order顺序错误,导致请求没有匹配到对应的链。securityMatcher是Spring Security6中用来定义当前安全链处理哪些请求的核心API,替代了旧版本中链级别的antMatchers。
内容的提问来源于stack exchange,提问作者hajjoujti
相关产品推荐
相关产品推荐

