如何使用 Spring Security 为 Spring Cloud Gateway 中的路由生成并传递 CSRF 令牌

问题描述 投票:0回答:1

我正在尝试使用

Okta
Spring Cloud Gateway
Spring Security
实现基于 Oauth2 的身份验证。我想要实现的目标是我希望 Spring Cloud Gateway 的路由可供所有人使用,而无需任何身份验证。我知道 Spring Cloud Gateway 使用
WebFlux
。因此,只有我在配置 Spring Security。 我在 Spring Cloud Gateway 中有三个路由。

  • /授权
  • /医生
  • /患者

我希望这些

/auth/**
路线中的任何一个都应该可供所有人使用,因为我的用户在这里注册,所以我不能在那里进行身份验证。对于另外两个
/doctors/**
/patients/**
我想要身份验证和授权。在云网关中的
SecurityConfig
中,我试图实现相同的目标。目前我已经做了这个配置:

    package com.sb.projects.medica.gateway.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
    import org.springframework.security.config.web.server.ServerHttpSecurity;
    import org.springframework.security.web.server.SecurityWebFilterChain;
    
    @Configuration
    @EnableWebFluxSecurity
    public class SecurityConfig {
        @Bean
        public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity httpSecurity) {
            httpSecurity.authorizeExchange(exchanges -> {
                exchanges.pathMatchers("/doctor/**", "/patient/**").authenticated();
                exchanges.pathMatchers("/auth/**").permitAll();
            }).oauth2Client().and().oauth2ResourceServer().jwt();
            return httpSecurity.build();
        }
    }

但似乎不起作用。当我尝试击中

/auth/**
的任何路线时,我得到

找不到预期的 CSRF 令牌

我该如何解决这个错误。如何创建 csrf 令牌并将其发送到前端

java spring-boot spring-security oauth-2.0 csrf
1个回答
2
投票

您显然刚刚开始 CSRF 配置之旅。我建议您从Spring 文档开始。就像真的一样。在阅读本答案的其余部分之前请仔细阅读。

网关后面的 REST API 可能可以配置为“无状态”(servlet 中的

http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
或反应式应用程序中的
http.securityContextRepository(NoOpServerSecurityContextRepository.getInstance())
),因此可以在其上禁用 CSRF 保护 (
http.csrf().disable() 
)。然后,您使用 OAuth2 授权配置 Postman 并直接查询 API(不通过网关)。

根据您的 React 前端配置为 OAuth2 公共客户端或网关配置为 Backend FFrontend(带有

TokenRelay
过滤器的 OAuth2 机密客户端),CSRF 保护的需求有很大不同:

  • 在第一种情况下,网关对安全性是透明的,并且由于它既不处理登录也不处理注销(两者都是由 React 应用程序中的 OAuth2 客户端库完成),也不处理与用户会话相关的任何内容,因此不需要担心 CSRF。然而,现在不鼓励这样做,转而采用 OAuth2 BFF 模式
  • 在第二种情况下,网关必须维护会话,授权代码流才能成功,并且
    TokenRelay
    过滤器才能工作(保持 OAuth2 令牌与每个浏览器会话关联)。因此,必须启用 CSRF,并且由于您的应用程序是基于 Javascript 的,因此必须启用 Cookie 存储库(
    http.csrf().csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse());
    在像
    spring-cloud-gateway
    这样的反应式应用程序上)。然后,您必须配置前端以将 CSRF 令牌(作为 cookie 接收)作为
    X-XSRF-TOKEN
    标头发送(如果您想通过网关发送请求而不是直接查询 API,则对 Postman 的要求相同)。我写了一个关于 Baeldung 的完整指南
© www.soinside.com 2019 - 2024. All rights reserved.