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

Spring Security 6.x中permitAll搭配addFilterAfter不生效问题

问题分析与解决方案

你遇到的这个问题其实是Spring Security过滤器链的执行逻辑导致的——过滤器的执行优先级在授权规则(比如permitAll)之前。也就是说,不管你给/swagger-ui/**这类路径配置了permitAll,只要你的JWTAuthorizationFilter被加到了过滤器链里,所有请求都会先经过这个过滤器,之后才会走到授权判断的环节。所以即使最终路径会被放行,过滤器还是会先执行一遍,这就是为什么移除过滤器后功能正常的原因。

下面给你几个实用的解决办法:

解决方案1:在JWT过滤器中跳过指定路径

直接修改你的JWTAuthorizationFilter,在核心过滤方法开头添加路径判断,如果是swagger相关路径,直接放行不做校验:

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    String requestURI = request.getRequestURI();
    // 判断是否是swagger相关路径,是的话直接跳过过滤逻辑
    if (requestURI.startsWith("/swagger-ui/") || requestURI.startsWith("/v3/api-docs/")) {
        filterChain.doFilter(request, response);
        return;
    }
    // 原来的JWT校验逻辑
    // ...
}

解决方案2:为swagger路径单独配置过滤器链

利用Spring Security多过滤器链的特性,给swagger路径配置一个优先级更高的、不带JWT过滤器的链,这样这些请求会先走这个链,不会进入带JWT过滤器的链:

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfiguration {

    public SecurityConfiguration() {}

    // 优先级更高的链,专门处理swagger路径
    @Bean
    @Order(0)
    public SecurityFilterChain swaggerFilterChain(HttpSecurity http) throws Exception {
        http
            .securityMatcher("/swagger-ui/**", "/v3/api-docs/**")
            .authorizeHttpRequests(authorize -> authorize
                .anyRequest().permitAll()
            );
        // 这里不添加JWT过滤器
        return http.build();
    }

    @Bean
    @Order(1)
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize
                .anyRequest().authenticated()
            )
            .addFilterAfter(new JWTAuthorizationFilter(), BasicAuthenticationFilter.class);

        return http.build();
    }
}

注意这里用了securityMatcher来限定这个链只处理指定路径,而且@Order(0)比原来的@Order(1)优先级更高,所以swagger请求会先走这个链,不会触发JWT过滤器。

解决方案3:限定JWT过滤器的作用路径

如果你不想拆分过滤器链,也可以通过FilterRegistrationBean来注册过滤器,并设置排除swagger路径:

@Bean
public FilterRegistrationBean<JWTAuthorizationFilter> jwtFilterRegistration() {
    FilterRegistrationBean<JWTAuthorizationFilter> registrationBean = new FilterRegistrationBean<>();
    registrationBean.setFilter(new JWTAuthorizationFilter());
    // 指定过滤器作用于所有路径,排除swagger相关路径
    registrationBean.addUrlPatterns("/*");
    registrationBean.addExcludeUrlPatterns("/swagger-ui/**", "/v3/api-docs/**");
    // 设置过滤器顺序,和原来的addFilterAfter逻辑对齐
    registrationBean.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE - 10);
    return registrationBean;
}

不过这种方式需要注意,如果你依赖@EnableWebSecurity自动管理过滤器链,可能需要调整配置逻辑,所以更推荐前两种方案。

内容的提问来源于stack exchange,提问作者piet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:25:44