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

Spring Cloud Gateway开启CSRF后登录POST拦截及默认登录页问题

问题根因

你遇到的两个问题分别由配置缺失、配置写法错误导致:

  • 默认登录页跳转问题:一是没有显式关闭Spring Security默认开启的表单登录、HTTP Basic认证能力,未认证请求访问受限路径时会自动触发默认登录页跳转;二是授权规则写法存在链式调用断裂问题,仅配置了/login路径的放行规则,未配置其余路径的访问逻辑,导致非/login请求全被默认认证规则拦截。
  • CSRF token缺失报错:WebFlux响应式环境下CsrfToken是惰性加载的,仅配置CookieServerCsrfTokenRepository不会主动触发token写入响应Cookie,前端Angular拿不到XSRF-TOKEN Cookie,发起POST登录请求时无法携带X-XSRF-TOKEN请求头,自然触发CSRF校验失败。
解决方案

1. 补全正确的安全配置

首先修正SecurityWebFilterChain的链式写法,关闭不需要的默认认证能力,补全授权规则,同时新增一个WebFilter主动触发CSRF token写入Cookie,完整配置如下:

@Configuration
@EnableWebFluxSecurity
public class NettyConfiguration implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {

    @Value("${server.max-initial-line-length:65536}")
    private int maxInitialLingLength;
    @Value("${server.max-http-header-size:65536}")
    private int maxHttpHeaderSize;

    @Override
    public void customize(NettyReactiveWebServerFactory container) {
        container.addServerCustomizers(
                httpServer -> httpServer.httpRequestDecoder(
                        httpRequestDecoderSpec -> {
                            httpRequestDecoderSpec.maxHeaderSize(maxHttpHeaderSize);
                            httpRequestDecoderSpec.maxInitialLineLength(maxInitialLingLength);
                            return httpRequestDecoderSpec;
                        }
                )
        );
    }

    /**
     * 主动触发CSRF token加载,写入响应Cookie
     */
    @Bean
    public WebFilter csrfCookieWebFilter() {
        return (exchange, chain) -> {
            exchange.getAttributeOrDefault(CsrfToken.class.getName(), Mono.empty())
                    .cast(CsrfToken.class)
                    .subscribe();
            return chain.filter(exchange);
        };
    }

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http
                // 关闭不需要的默认认证机制,避免跳默认登录页
                .formLogin(ServerHttpSecurity.FormLoginSpec::disable)
                .httpBasic(ServerHttpSecurity.HttpBasicSpec::disable)
                // 跨域场景开启,需提前配置CorsConfigurationSource
                .cors(Customizer.withDefaults())
                .csrf(csrf -> csrf
                        // 配置Cookie存储CSRF token,关闭HttpOnly允许前端JS读取
                        .csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse())
                )
                .authorizeExchange(exchanges -> exchanges
                        // 放行所有OPTIONS预检请求,跨域场景必须
                        .pathMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                        // 放行登录接口
                        .pathMatchers("/login").permitAll()
                        // 其余路径根据业务需求配置,示例为需要认证,可自行调整
                        .anyExchange().authenticated()
                );
        return http.build();
    }
}

2. 跨域场景额外配置

如果前端Angular服务和网关不同域,还需要做两处配置:

  • 网关侧配置CORS规则:允许前端域名作为访问源、允许携带凭证、允许X-XSRF-TOKEN请求头;同时给CookieServerCsrfTokenRepository配置Cookie的sameSite属性为None(HTTPS环境下)、domain为前后端共同的父域名,确保跨域场景下Cookie可正常写入。
  • 前端Angular侧:发起HTTP请求时开启withCredentials: true,允许跨域请求携带Cookie。Angular默认的HttpClient已经实现了自动读取XSRF-TOKEN Cookie、自动往非GET请求里加X-XSRF-TOKEN请求头的逻辑,不需要额外写拦截器处理。
注意事项
  • 不要为了绕过CSRF校验把/login路径加入CSRF白名单,会导致登录接口失去CSRF防护,存在安全风险。
  • 确保前端加载时第一个发起的GET请求能正常触达网关,CSRF Cookie会在该请求的响应中被自动写入,后续业务请求会自动携带token完成校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 14:42:33