路由謂詞工廠

Spring Cloud Gateway 將路由匹配作為 Spring WebFlux HandlerMapping 基礎設施的一部分。Spring Cloud Gateway 包含許多內建的路由斷言工廠。所有這些斷言都匹配 HTTP 請求的不同屬性。您可以將多個路由斷言工廠與邏輯 and 語句結合使用。

After 路由斷言工廠

After 路由斷言工廠接受一個引數:一個 datetime(即 Java ZonedDateTime)。此斷言匹配在指定日期時間之後發生的請求。以下示例配置了一個 After 路由斷言

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]

此路由匹配在 2017 年 1 月 20 日 17:42 山區時間(丹佛)之後發出的任何請求。

Before 路由斷言工廠

Before 路由斷言工廠接受一個引數:一個 datetime(即 Java ZonedDateTime)。此斷言匹配在指定 datetime 之前發生的請求。以下示例配置了一個 Before 路由斷言

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: https://example.org
        predicates:
        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

此路由匹配在 2017 年 1 月 20 日 17:42 山區時間(丹佛)之前發出的任何請求。

Between 路由斷言工廠

Between 路由斷言工廠接受兩個引數:datetime1datetime2,它們是 Java ZonedDateTime 物件。此斷言匹配在 datetime1 之後且在 datetime2 之前發生的請求。datetime2 引數必須在 datetime1 之後。以下示例配置了一個 Between 路由斷言

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

此路由匹配在 2017 年 1 月 20 日 17:42 山區時間(丹佛)之後和 2017 年 1 月 21 日 17:42 山區時間(丹佛)之前發出的任何請求。這對於維護視窗可能很有用。

Cookie 路由斷言工廠接受兩個引數:cookie name 和一個 regexp(即 Java 正則表示式)。此斷言匹配具有給定名稱且其值與正則表示式匹配的 cookie。以下示例配置了一個 Cookie 路由斷言工廠

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        - Cookie=chocolate, ch.p

此路由匹配具有名為 chocolate 的 cookie 且其值與 ch.p 正則表示式匹配的請求。

Header 路由斷言工廠

Header 路由斷言工廠接受兩個引數:header 和一個 regexp(即 Java 正則表示式)。此斷言匹配具有給定名稱且其值與正則表示式匹配的請求頭。以下示例配置了一個 Header 路由斷言

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://example.org
        predicates:
        - Header=X-Request-Id, \d+

如果請求具有名為 X-Request-Id 的請求頭,且其值與 \d+ 正則表示式匹配(即,其值為一個或多個數字),則此路由匹配。

Host 路由斷言工廠

Host 路由斷言工廠接受一個引數:主機名 patterns 列表。模式是一個 Ant 風格的模式,以 . 作為分隔符。此斷言匹配與模式匹配的 Host 請求頭。以下示例配置了一個 Host 路由斷言

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Host=**.somehost.org,**.anotherhost.org

也支援 URI 模板變數(例如 {sub}.myhost.org)。

如果請求具有 Host 請求頭,且其值為 www.somehost.orgbeta.somehost.orgwww.anotherhost.org,則此路由匹配。

此斷言將 URI 模板變數(例如前面示例中定義的 sub)提取為名稱和值的對映,並將其放在 ServerWebExchange.getAttributes() 中,鍵由 ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE 定義。這些值隨後可用於 GatewayFilter 工廠

Method 路由斷言工廠

Method 路由斷言工廠接受一個 methods 引數,該引數是一個或多個 HTTP 方法引數,用於匹配。以下示例配置了一個 Method 路由斷言

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        - Method=GET,POST

如果請求方法為 GETPOST,則此路由匹配。

Path 路由斷言工廠

Path 路由斷言工廠接受兩個引數:一個 Spring PathMatcher patterns 列表和一個可選的 matchTrailingSlash 標誌(預設為 true)。以下示例配置了一個 Path 路由斷言

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment},/blue/{segment}

如果請求路徑為例如:/red/1/red/1//red/blue/blue/green,則此路由匹配。

如果將 matchTrailingSlash 設定為 false,則請求路徑 /red/1/ 將不匹配。

如果您設定了 spring.webflux.base-path 屬性,這將影響路徑匹配。屬性值將自動新增到路徑模式的前面。例如,如果 spring.webflux.base-path=/app 且路徑模式為 /red/{segment},則用於匹配的完整模式將是 /app/red/{segment}

此斷言將 URI 模板變數(例如前面示例中定義的 segment)提取為名稱和值的對映,並將其放在 ServerWebExchange.getAttributes() 中,鍵由 ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE 定義。這些值隨後可用於 GatewayFilter 工廠

提供了一個實用方法(稱為 get)以方便訪問這些變數。以下示例展示瞭如何使用 get 方法

Map<String, String> uriVariables = ServerWebExchangeUtils.getUriTemplateVariables(exchange);

String segment = uriVariables.get("segment");

Query 路由斷言工廠

Query 路由斷言工廠接受兩個引數:一個必需的 param 和一個可選的 regexp(即 Java 正則表示式)。以下示例配置了一個 Query 路由斷言

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=green

如果請求包含 green 查詢引數,則前面的路由匹配。

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=red, gree.

如果請求包含 red 查詢引數,且其值匹配 gree. 正則表示式,則前面的路由匹配,因此 greengreet 將匹配。

RemoteAddr 路由斷言工廠

RemoteAddr 路由斷言工廠接受一個 sources 列表(最小長度為 1),這些源是 CIDR 表示法(IPv4 或 IPv6)字串,例如 192.168.0.1/16(其中 192.168.0.1 是 IP 地址,16 是子網掩碼)。以下示例配置了一個 RemoteAddr 路由斷言

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: https://example.org
        predicates:
        - RemoteAddr=192.168.1.1/24

如果請求的遠端地址為例如 192.168.1.10,則此路由匹配。

修改遠端地址的解析方式

預設情況下,RemoteAddr 路由斷言工廠使用來自傳入請求的遠端地址。如果 Spring Cloud Gateway 位於代理層之後,這可能與實際客戶端 IP 地址不匹配。

您可以透過設定自定義的 RemoteAddressResolver 來定製遠端地址的解析方式。Spring Cloud Gateway 附帶一個非預設的遠端地址解析器,該解析器基於 X-Forwarded-For 請求頭,即 XForwardedRemoteAddressResolver

XForwardedRemoteAddressResolver 有兩個靜態構造方法,它們採用不同的安全方法

  • XForwardedRemoteAddressResolver::trustAll 返回一個 RemoteAddressResolver,它始終獲取 X-Forwarded-For 請求頭中找到的第一個 IP 地址。這種方法容易受到欺騙,因為惡意客戶端可以為 X-Forwarded-For 設定初始值,該值將被解析器接受。

  • XForwardedRemoteAddressResolver::maxTrustedIndex 接受一個索引,該索引與 Spring Cloud Gateway 前面執行的受信任基礎設施的數量相關。例如,如果 Spring Cloud Gateway 只能透過 HAProxy 訪問,則應使用值 1。如果在 Spring Cloud Gateway 可訪問之前需要兩次受信任基礎設施的跳躍,則應使用值 2。

考慮以下請求頭值

X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3

以下 maxTrustedIndex 值產生以下遠端地址

maxTrustedIndex 結果

[Integer.MIN_VALUE,0]

(無效,初始化時發生 IllegalArgumentException

1

0.0.0.3

2

0.0.0.2

3

0.0.0.1

[4, Integer.MAX_VALUE]

0.0.0.1

以下示例展示瞭如何使用 Java 實現相同的配置

GatewayConfig.java
RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
    .maxTrustedIndex(1);

...

.route("direct-route",
    r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")
        .uri("https://downstream1")
.route("proxied-route",
    r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24")
        .uri("https://downstream2")
)

Weight 路由斷言工廠

Weight 路由斷言工廠接受兩個引數:groupweight(一個整數)。權重按組計算。以下示例配置了一個 Weight 路由斷言

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: weight_high
        uri: https://weighthigh.org
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: https://weightlow.org
        predicates:
        - Weight=group1, 2

此路由將把約 80% 的流量轉發到 weighthigh.org,將約 20% 的流量轉發到 weightlow.org

XForwarded Remote Addr 路由斷言工廠

XForwarded Remote Addr 路由斷言工廠接受一個 sources 列表(最小長度為 1),這些源是 CIDR 表示法(IPv4 或 IPv6)字串,例如 192.168.0.1/16(其中 192.168.0.1 是 IP 地址,16 是子網掩碼)。

此路由斷言允許根據 X-Forwarded-For HTTP 請求頭過濾請求。

這可以與負載均衡器或 Web 應用程式防火牆等反向代理一起使用,其中只有當請求來自這些反向代理使用的受信任 IP 地址列表時才允許請求。

以下示例配置了一個 XForwardedRemoteAddr 路由斷言

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: xforwarded_remoteaddr_route
        uri: https://example.org
        predicates:
        - XForwardedRemoteAddr=192.168.1.1/24

如果 X-Forwarded-For 請求頭包含例如 192.168.1.10,則此路由匹配。

© . This site is unofficial and not affiliated with VMware.