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

Spring WebFlux Security中permitAll()无法跳过令牌验证过滤器问题

问题根源

你遇到的核心问题是:permitAll()控制的是授权决策环节,而你添加的令牌验证过滤器是在认证阶段执行的,它不会自动识别授权规则里的放行路径。

Spring WebFlux Security的过滤器链执行顺序是:

  1. 各种前置过滤器(包括你添加的tokenValidation)
  2. 认证过滤器
  3. 授权决策(也就是permitAll()/authenticated()生效的环节)

所以哪怕你给/auth/api/v1/cred/**配置了permitAll(),请求还是会先经过tokenValidation过滤器,再进入授权判断环节——这时候授权环节会放行,但过滤器已经执行过了。

解决方案

有两种常用的解决方式,根据你的场景选择:

方案1:在令牌验证过滤器内主动跳过指定路径

修改tokenValidation的逻辑,先判断请求路径是否属于放行范围,如果是就直接跳过验证:

@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    String requestPath = exchange.getRequest().getPath().value();
    // 匹配所有/auth/api/v1/cred开头的路径
    if (requestPath.startsWith("/auth/api/v1/cred/")) {
        return chain.filter(exchange);
    }
    // 原来的令牌验证逻辑
    // ...
}

这种方式适合过滤器逻辑简单、只想跳过少量路径的场景。

方案2:拆分SecurityWebFilterChain,为放行路径单独配置

创建两个优先级不同的SecurityWebFilterChain,让放行路径的配置先执行,且不添加令牌验证过滤器:

第一个配置(处理放行路径,优先级更高)

@Bean
@Order(1) // 数字越小优先级越高
public SecurityWebFilterChain publicEndpointSecurity(ServerHttpSecurity http) throws Exception {
    http
        .securityMatcher("/auth/api/v1/cred/**") // 只对该路径生效
        .csrf(ServerHttpSecurity.CsrfSpec::disable)
        .authorizeExchange(exchanges -> exchanges.anyExchange().permitAll())
        .httpBasic(ServerHttpSecurity.HttpBasicSpec::disable)
        .formLogin(ServerHttpSecurity.FormLoginSpec::disable);
    return http.build();
}

第二个配置(处理其他所有需要认证的路径)

@Bean
@Order(2)
public SecurityWebFilterChain securedEndpointSecurity(ServerHttpSecurity http) throws Exception {
    http
        .csrf(ServerHttpSecurity.CsrfSpec::disable)
        .authorizeExchange(exchanges -> exchanges.anyExchange().authenticated())
        .addFilterBefore(tokenValidation, SecurityWebFiltersOrder.AUTHENTICATION)
        .addFilterAfter(addXTrustedSourceHeaderFilter, SecurityWebFiltersOrder.AUTHENTICATION)
        .httpBasic(ServerHttpSecurity.HttpBasicSpec::disable)
        .formLogin(ServerHttpSecurity.FormLoginSpec::disable);
    return http.build();
}

这种方式更清晰,适合有大量不同权限规则的场景,每个配置只负责自己的路径范围。

额外验证点
  • 确认应用是否有上下文路径:如果你的应用部署时带有上下文路径(比如/api),那么pathMatchers里需要写成/api/auth/api/v1/cred/**,或者结合server.servlet.context-path配置调整匹配规则。
  • 检查路径匹配规则:/**会匹配该路径下的所有子路径,/auth/api/v1/cred/login/确实会被/auth/api/v1/cred/**匹配到,这点你已经确认过,没问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 09:24:59