You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 19:37:43