簡體   English   中英

Spring雲網關+Spring安全資源服務器

[英]Spring Cloud Gateway + Spring security resource server

我真的不會把它放在這里但我真的很困惑,我想實現以下目標。

我在跑步

  • Java 14
  • Spring Cloud Gateway版本: Hoxton.SR3
  • Spring Boot版本: 2.2.5.RELEASE

現在我想將安全性集成到我的網關和所有下游微服務中。 最終,我決定將 go 與 Firebase 作為身份提供者 (IDP)。 我的 Angular 應用程序將從 Firebase 獲取 JWT 令牌,並將其在每個請求中發送到雲網關。 因此,網關將開始僅充當資源服務器,僅此而已。

在這里,我如何嘗試給它一個 go。 同時設置Spring Cloud Gateway充當資源服務器。 Spring Security Docs在這里解釋得很好。

這是我的配置的樣子

@EnableWebFluxSecurity
public class ResourceServerSecurityConfiguration {

  @Bean
  public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
    // @formatter:off
    http
        .authorizeExchange()
        .anyExchange().authenticated()
        .and()
        .oauth2ResourceServer()
        .jwt();
    return http.build();
    // @formatter:on
  }
}

和 application.yml

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          jwk-set-uri: https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com
          issuer-uri: https://securetoken.google.com/{$app.name}

正如您在此 YAML 中看到的,我提供了 jwk-set-uri 和頒發者來驗證傳入的令牌。

在這一點上,所有的工作都被接受了。 所有請求都必須在身份驗證 header 中具有有效的 JWT。

下一個,

我希望我的網關使用WebClient並調用多個服務來為前端聚合數據。

這是我嘗試配置客戶端的方式。

  @Bean
  @LoadBalanced
  public WebClient.Builder loadBalancedWebClientBuilder() {
    return WebClient.builder()
        .filter(new ServletBearerExchangeFilterFunction());
  }

如您所見,它使用ServletBearerExchangeFilterFunction這是我真正的問題所在。

我已經檢查過,當 Spring 配置 oauth2ResourceServer 時,它使用NoOpServerSecurityContextRepository 據我所知,這正是一個用於為每個請求注冊上下文的存儲庫。 另外,我知道使用 NoOp 是有意義的,因為我們希望是無狀態的。 但是,我不明白如何使ServletBearerExchangeFilterFunction正常工作並將我的令牌傳遞到下游。

我現在花了很多時間試圖找出正確的方法。

發現這個: Spring Boot 2 OIDC (OAuth2) 客戶端/資源服務器未在 WebClient 中傳播訪問令牌

Github: https://github.com/spring-projects/spring-security/issues/7771

即使根據這一點,我嘗試做的事情也應該是合法和可能的。 不知道我錯在哪里。

Spring 雲網關旨在提供一種簡單而有效的方式來路由到 API 並為它們提供橫切關注點,例如:安全性、監控/指標和彈性。

如果你將 SCG(Spring Cloud Gateway) 設置為 oauth2 資源服務器,你必須做更多的自定義,也許像這樣 我認為你不應該那樣做。

您可以使用網關作為路由,並將訪問令牌header發送到SCG,SCG將訪問令牌帶到oauth2資源服務器,並檢查oauth2資源服務器端的權限。

Spring 雲網關令牌中繼網關過濾器工廠說:

{githubmaster}/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java[filter] 從當前經過身份驗證的用戶中提取訪問令牌,並將其放入下游請求的請求 header 中。

這樣可以在您的應用程序中保持 oauth2 的清晰性。

我想這一點,事情是 ReactiveSecurityContext 僅當您在反應流中可用並且 ServletBearerExchangeFilterFunction 用於 Servlet 調用時才可用。

最后,我只寫了自己的過濾器 function,它監聽 ReactiveSecurity 上下文並設置授權 header。 這里是。

public class BearerExchangeFilterFunction implements ExchangeFilterFunction {

  @Override
  @NonNull
  public Mono<ClientResponse> filter(@NonNull ClientRequest request, ExchangeFunction next) {
    return ReactiveSecurityContextHolder.getContext()
        .map(c -> (c.getAuthentication().getCredentials()))
        .cast(AbstractOAuth2Token.class)
        .checkpoint()
        .map(token -> bearer(request, token))
        .defaultIfEmpty(request)
        .flatMap(next::exchange);
  }

  private ClientRequest bearer(ClientRequest request, AbstractOAuth2Token token) {
    return ClientRequest.from(request)
        .headers(headers -> headers.setBearerAuth(token.getTokenValue()))
        .build();
  }


}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM