首页 > 解决方案 > Spring Cloud Gateway 在调用资源服务器后删除 SESSION cookie

问题描述

SESSION在调用资源服务器后,我遇到了 Spring Cloud Gateway 重置 cookie 的问题。

我有一个 Angular 应用程序、一个 Spring Cloud Gateway 应用程序、一个外部授权服务器和一个我自己的资源服务器。

Angular 应用程序首先通过 Spring Cloud Gateway 应用程序(使用 OAuth2 将这项工作委托给外部授权服务器)进行授权并接收SESSIONcookie。此时用户已通过身份验证,并且Authentication对象在 Spring Cloud Gateway 应用程序中可用。

接下来,Angular 应用程序调用 Spring Cloud Gateway 应用程序的一个端点,该端点实际上将调用转发到资源服务器(并在调用中包含 Bearer 令牌,因此调用正常),资源服务器返回一些结果,即成功通过 Spring Cloud Gateway 应用程序发送回 Angular 应用程序。但是除了成功响应之外,Spring Cloud Gateway 应用程序还会发送此标头:

set-cookie: SESSION=; Max-Age=0; Expires=Sat, 17 Aug 2019 20:39:44 GMT; Path=/; HTTPOnly

这会杀死客户端的 cookie 并使后续调用变得不可能,即使该Authentication对象仍然存在并且会话看起来也很好。

有谁知道这种行为的原因是什么?

标签: sessioncookiessession-cookiesspring-cloudspring-cloud-gateway

解决方案


我们在 WebFlux 资源服务器中遇到了确切的问题——API 网关会将请求代理到资源服务器,因此第一个请求有效,但随后的请求将尝试再次进行身份验证,因为SESSIONcookie 已被清除,从而导致一些X-XSRF-TOKEN错误。

我们通过在 WebFlux 资源服务器中添加 bean 定义.requestCache().requestCache(NoOpServerRequestCache.getInstance())来解决这个问题。securityWebFilterChain

@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
class ResourceServerConfiguration {

    @Value('${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}')
    String jwkSetUri

    @Bean
    SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http
                .csrf().disable()     
                .requestCache().requestCache(NoOpServerRequestCache.getInstance()).and()
                .httpBasic().disable()
                .formLogin().disable()
                .oauth2ResourceServer().jwt().jwkSetUri(jwkSetUri)
                .and().and()
                .authorizeExchange()
                .pathMatchers("/v1/**").authenticated()                
    }
}

在“经典”MVC 世界中,您可以ResourceServerConfigurer像这样配置您的类:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.sessionManagement()
    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

推荐阅读