如何在 Spring 云网关上传递访问令牌

How to Pass access token on Spring Cloud Gateway

我是 OAuth2 和 Spring 云网关(以及 WebFlux 东西)的新手。

我的团队决定从 Zuul 网关迁移到 Spring 云网关。 当前 Spring 云版本为 "Greenwich.SR1"

问题是spring云网关总是响应401。

如何在 Spring 云网关上正确传递访问令牌?

授权服务器:

@EnableEurekaClient
@EnableAuthorizationServer
@SpringBootApplication
public class AuthServer {...} // jwtAccessTokenConverter bean included

Zuul 服务器是:

@EnableEurekaClient
@EnableZuulProxy
@SpringBootApplication
public class ZuulServer {...}

Zuul 服务器属性:

zuul:
  sensitive-headers: Cookie,Set-Cookie
  ignored-services: '*'
  routes:
    auth: /auth/**

Spring 云网关服务器属性:

spring:
  cloud:
    gateway:
      routes:
        - id: auth
          uri: lb://auth
          predicates:
            - Method=POST
            - Path=/auth/**
          filters:
            - RemoveRequestHeader= Cookie,Set-Cookie
            - StripPrefix=1

Spring 云服务器 build.gradle :

plugins {
    id 'java'
    id "io.freefair.lombok" version "3.2.0"
    id "org.springframework.boot" version "2.1.5.RELEASE"
    id "io.spring.dependency-management" version "1.0.6.RELEASE"
}

version = '1.0.0-SNAPSHOT'
description = 'edge-service2'
sourceCompatibility = '11'

dependencies {
    implementation platform("org.springframework.cloud:spring-cloud-dependencies:$springCloudVersion")
    implementation "org.springframework.boot:spring-boot-starter-security"
    implementation "org.springframework.cloud:spring-cloud-starter-netflix-eureka-client"
    implementation "org.springframework.cloud:spring-cloud-starter-netflix-ribbon"
    implementation "org.springframework.cloud:spring-cloud-starter-netflix-hystrix"

    implementation('org.springframework.cloud:spring-cloud-starter-gateway')

    implementation "org.springframework.cloud:spring-cloud-config-client"
    implementation "de.codecentric:spring-boot-admin-starter-client:$springBootAdminVersion"
    implementation "net.gpedro.integrations.slack:slack-webhook:1.4.0"
    testImplementation "org.springframework.boot:spring-boot-starter-test"
}


springBoot {
    buildInfo()
}

bootJar {
    archiveName "${project.name}.jar"
}

Spring Cloud Security 中有一项功能可通过 Spring Cloud Gateway 将访问令牌中继到下游服务:https://cloud.spring.io/spring-cloud-static/spring-cloud-security/2.1.3.RELEASE/single/spring-cloud-security.html#_token_relay

只需将 TokenRelay 过滤器用于您的路由或默认配置。 但是,这只会转发访问令牌。 “访问令牌是允许客户端应用程序访问用户资源的工件”[1],而“ID 令牌是证明用户已通过身份验证的工件”[1],它还包含用户属性.

这似乎就是您想要的,但对于所有使用 OIDC 并希望中继 ID 令牌的人,这里有更多信息。 在以下位置编写自定义 GatewayFilterFactory:

  • 通过 exchange.getPrincipal().ofType(OAuth2AuthenticationToken.class)
  • 获取经过身份验证的 Principal
  • 映射它直到你得到一个 oAuth2User 对象
  • 将其转换为 OidcUser
  • 现在你可以做 oidcUser.getIdToken.getTokenValue()
  • 将其放入您选择的 header 中,因此您还可以转发 ID 令牌,而不仅仅是访问令牌。

[1] https://auth0.com/blog/id-token-access-token-what-is-the-difference/