114. Route Predicate Factories

Spring Cloud Gateway 将 routes 作为 Spring WebFlux HandlerMapping基础结构的一部分进行匹配。 Spring Cloud Gateway 包含许多 built-in Route Predicate Factories。所有这些谓词都匹配 HTTP 请求的不同属性。多个 Route 谓词工厂可以组合并通过逻辑and组合。

114.1 Route 谓词工厂之后

After Route Predicate Factory 采用一个参数 datetime。此谓词匹配当前 datetime 之后发生的请求。

application.yml.

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

此 route 符合 2017 年 1 月 20 日 17:42 Mountain Time(丹佛)之后的任何请求。

114.2 在 Route Predicate Factory 之前

Before Route Predicate Factory 采用一个参数 datetime。此谓词匹配当前 datetime 之前发生的请求。

application.yml.

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

此 route 在 2017 年 1 月 20 日之前匹配任何请求 17:42 Mountain Time(丹佛)。

114.3 Route 谓词工厂之间

Between Route 谓词工厂有两个参数,datetime1 和 datetime2。此谓词匹配 datetime1 之后和 datetime2 之前发生的请求。 datetime2 参数必须在 datetime1 之后。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: http://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 Mountain Time(丹佛)之后以及 2017 年 1 月 21 日 17:42 Mountain Time(丹佛)之前,此 route 符合任何请求。这可能对维护 windows 有用。

Cookie Route 谓词工厂有两个参数,cookie name 和正则表达式。此谓词匹配具有给定 name 且 value 与正则表达式匹配的 cookies。

application.yml.

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

这个 route 匹配请求有一个名为chocolate的 cookie,其 value 与ch.p正则表达式匹配。

114.5 Header Route Predicate Factory

Header Route 谓词工厂有两个参数,头 name 和正则表达式。此谓词与具有给定 name 且 value 与正则表达式匹配的标头匹配。

application.yml.

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

如果请求具有名为X-Request-Id的标头,则此 route 匹配,其中 value 与\d+正则表达式匹配(具有一个或多个数字的 value)。

114.6 Host Route Predicate Factory

Host Route 谓词工厂有一个参数:host name pattern。 pattern 是 Ant 样式 pattern,.作为分隔符。此谓词匹配与 pattern 匹配的Host标头。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: http://example.org
        predicates:
        - Host=**.somehost.org

如果请求的Host标头具有 value www.somehost.orgbeta.somehost.org,则此 route 将 match。

114.7 方法路由谓词工厂

方法 Route Predicate Factory 采用一个参数:HTTP 方法到 match。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: http://example.org
        predicates:
        - Method=GET

如果请求方法是GET,则 route 将 match。

114.8 Path Route Predicate Factory

Path Route Predicate Factory 采用一个参数:Spring PathMatcher pattern。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: http://example.org
        predicates:
        - Path=/foo/{segment}

对于 example:/foo/1/foo/bar,如果请求路径为 match,则此 route 将匹配。

此谓词将 URI 模板变量(如上面 example 中定义的segment)提取为名称和值的 map,并将其放在ServerWebExchange.getAttributes()中,并在PathRoutePredicate.URL_PREDICATE_VARS_ATTR中定义 key。这些值随后可供GatewayFilter 工厂使用

114.9 查询 Route 谓词工厂

Query Route Predicate Factory 有两个参数:一个必需的param和一个可选的regexp

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: http://example.org
        predicates:
        - Query=baz

如果请求包含baz查询参数,则此 route 将匹配。

application.yml.

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: http://example.org
        predicates:
        - Query=foo, ba.

如果请求包含查询参数,其 value 与ba. regexp 匹配,则 route 将 match,因此barbaz将 match。

114.10 RemoteAddr Route Predicate Factory

RemoteAddr Route Predicate Factory 获取 CIDR-notation(IPv4 或 IPv6)strings,e.g 的列表(最小值为 1)。 192.168.0.1/16(其中192.168.0.1是 IP 地址,16是子网掩码)。

application.yml.

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

如果请求的 remote 地址是 example,那么 route 将匹配192.168.1.10

114.10.1 修改 remote 地址的解析方式

默认情况下,RemoteAddr Route 谓词工厂使用传入请求中的 remote 地址。如果 Spring Cloud Gateway 位于代理层后面,则可能不匹配实际的 client IP 地址。

您可以通过设置自定义RemoteAddressResolver来自定义解决 remote 地址的方式。 Spring Cloud Gateway 附带一个 non-default remote 地址解析器,它基于X-Forwarded-For 标题XForwardedRemoteAddressResolver

XForwardedRemoteAddressResolver有两个静态构造函数方法,它们采用不同的安全方法:

XForwardedRemoteAddressResolver::trustAll返回RemoteAddressResolver,它总是占用X-Forwarded-For标头中的第一个 IP 地址。这种方法容易受到欺骗,因为恶意 client 可以为X-Forwarded-For设置初始值,这将被解析器接受。

XForwardedRemoteAddressResolver::maxTrustedIndex采用与 Spring Cloud Gateway 前面的可信基础设施数量相关的索引。如果 Spring Cloud Gateway 是 example 只能通过 HAProxy 访问,那么应该使用 value 为 1。如果在可以访问 Spring Cloud Gateway 之前需要两跳受信任的基础架构,则应使用 value 为 2。

给出以下标题 value:

X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3

下面的maxTrustedIndex值将 yield 以下 remote 地址。

maxTrustedIndex结果
[ Integer.MINVALUE,0](无效,初始化期间IllegalArgumentException)
10.0.0.3
20.0.0.2
30.0.0.1
[4,Integer.MAXVALUE]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")
)