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

Spring Cloud Gateway配置Basic Auth后下游请求返回401问题排查

问题分析与解决方案

我来帮你捋捋这个配置失效的核心原因——第一个SecurityWebFilterChain没有限定处理的请求范围,导致所有请求都先经过它,而非Actuator的请求因为没匹配到对应的授权规则,被Spring Security默认拒绝,直接返回401,第二个过滤器链根本没机会生效。

具体问题拆解

你当前的@Order(1)过滤器链,只配置了针对Actuator端点的授权规则,但没有通过securityMatcher指定它仅处理Actuator路径的请求。Spring Security的SecurityWebFilterChain如果不设置匹配规则,会默认拦截所有请求。这就导致:

  • 当请求是下游服务的非Actuator端点时,会先进入第一个过滤器链,但因为没匹配到matchers里的Actuator规则,Spring Security会执行默认的denyAll逻辑,直接返回401。
  • 第二个@Order(2)的过滤器链完全被跳过,根本没机会处理下游服务的请求。

正确配置方案

我们需要给第一个过滤器链明确指定只处理Actuator请求,让非Actuator请求流转到第二个链处理。调整后的代码如下:

import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.actuate.info.InfoEndpoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Order;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import static org.springframework.security.config.Customizer.withDefaults;

@EnableWebFluxSecurity
public class GatewaySecurityConfig {

    @Bean
    @Order(1)
    SecurityWebFilterChain actuatorSecurityFilterChain(final ServerHttpSecurity http) {
        http
            // 明确只匹配所有Actuator端点的请求
            .securityMatcher(ServerHttpSecurity.PathMatchers.ant("/actuator/**"))
            .authorizeExchange(exchanges -> exchanges
                // 允许health和info端点匿名访问
                .matchers(ServerHttpSecurity.PathMatchers.ant("/actuator/health", "/actuator/info")).permitAll()
                // 其他Actuator端点(包括/refresh)需要ACTUATOR角色认证
                .anyExchange().hasRole("ACTUATOR")
            )
            // 启用Basic Auth用于Actuator的身份验证
            .httpBasic(withDefaults());
        
        return http.build();
    }

    @Bean
    @Order(2)
    SecurityWebFilterChain downstreamServiceSecurityFilterChain(final ServerHttpSecurity http) {
        http
            // 处理所有非Actuator的请求
            .authorizeExchange(exchanges -> exchanges.anyExchange().permitAll())
            // 禁用Basic Auth,避免干扰下游服务的请求转发
            .httpBasic(ServerHttpSecurity.HttpBasicSpec::disable)
            // 关闭CSRF保护(网关转发请求不需要这个,默认开启会拦截部分POST请求)
            .csrf(csrf -> csrf.disable())
            // 关闭默认的表单登录(网关不需要这个)
            .formLogin(form -> form.disable());
        
        return http.build();
    }
}

额外配置注意事项

别忘了在application.properties(或application.yml)里配置Spring Security的用户信息:

# Spring Security用户配置
spring.security.user.name=gateway-admin
spring.security.user.password=your-secure-password
spring.security.user.roles=ACTUATOR

测试验证

  • 访问/actuator/refresh:会弹出Basic Auth登录框,输入配置的用户名密码后才能正常访问。
  • 访问下游服务的端点(比如/api/user/list):不管有没有携带Basic Auth信息,都会直接转发到下游服务,返回正常的200响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 20:27:37