5. 路由谓词工厂

Spring Cloud 网关将路由作为 Spring WebFlux 的一部分进行匹配HandlerMapping基础设施。 Spring Cloud 网关包括许多内置的路由谓词工厂。 所有这些谓词都与 HTTP 请求的不同属性匹配。 您可以将多个路由谓词工厂与逻辑and语句。spring-doc.cadn.net.cn

5.1. After Route 谓词工厂

AfterRoute Predicate Factory 接受一个参数,即datetime(这是一个 JavaZonedDateTime). 此谓词匹配在指定日期/时间之后发生的请求。 以下示例配置 after 路由谓词:spring-doc.cadn.net.cn

示例 1.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 山区时间(丹佛)之后发出的任何请求。spring-doc.cadn.net.cn

5.2. Before Route 谓词工厂

BeforeRoute Predicate Factory 接受一个参数,即datetime(这是一个 JavaZonedDateTime). 此谓词匹配在指定的datetime. 以下示例配置 before route 谓词:spring-doc.cadn.net.cn

示例 2.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 山区时间(丹佛)之前发出的任何请求。spring-doc.cadn.net.cn

5.3. Between 路由谓词工厂

BetweenRoute Predicate Factory 接受两个参数,datetime1datetime2哪些是 JavaZonedDateTime对象。 此谓词匹配在datetime1和之前datetime2. 这datetime2parameter 必须在datetime1. 以下示例配置了 between 路由谓词:spring-doc.cadn.net.cn

例 3.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 山区时间(丹佛)之前发出的任何请求。 这对于维护时段可能很有用。spring-doc.cadn.net.cn

CookieRoute Predicate Factory 接受两个参数,即 cookiename以及regexp(这是一个 Java 正则表达式)。 此谓词匹配具有给定名称且其值与正则表达式匹配的 Cookie。 以下示例配置 cookie 路由谓词工厂:spring-doc.cadn.net.cn

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

此路由匹配具有名为chocolate其值与ch.p正则表达式。spring-doc.cadn.net.cn

5.5. Header 路由谓词工厂

HeaderRoute Predicate Factory 采用两个参数,header以及regexp(这是一个 Java 正则表达式)。 此谓词与具有给定名称的 Headers 匹配,该 Headers 的值与正则表达式匹配。 以下示例配置标头路由谓词:spring-doc.cadn.net.cn

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

如果请求具有名为X-Request-Id其值与\d+正则表达式(即,它的值为一个或多个数字)。spring-doc.cadn.net.cn

5.6. 主机路由谓词工厂

HostRoute Predicate Factory 接受一个参数:主机名列表patterns. 该模式是 Ant 样式的模式,具有.作为分隔符。 此谓词与Host标头。 以下示例配置主机路由谓词:spring-doc.cadn.net.cn

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

URI 模板变量(例如{sub}.myhost.org) 也受支持。spring-doc.cadn.net.cn

如果请求具有Host标头,其值为www.somehost.orgbeta.somehost.orgwww.anotherhost.org.spring-doc.cadn.net.cn

此谓词提取 URI 模板变量(例如sub,作为名称和值的映射,并将其放置在ServerWebExchange.getAttributes()ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE. 然后,这些值可供GatewayFilter工厂spring-doc.cadn.net.cn

5.7. Method Route Predicate Factory

MethodRoute Predicate Factory 采用methods参数(可以是一个或多个参数):要匹配的 HTTP 方法。 以下示例配置方法路由谓词:spring-doc.cadn.net.cn

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

如果请求方法是GETPOST.spring-doc.cadn.net.cn

5.8. 路径路由谓词工厂

PathRoute Predicate Factory 采用两个参数:SpringPathMatcher patterns和一个名为matchTrailingSlash(默认为true). 以下示例配置路径路由谓词:spring-doc.cadn.net.cn

例 8.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.spring-doc.cadn.net.cn

如果matchTrailingSlash设置为false,然后请求路径/red/1/将不匹配。spring-doc.cadn.net.cn

此谓词提取 URI 模板变量(例如segment,作为名称和值的映射,并将其放置在ServerWebExchange.getAttributes()ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE. 然后,这些值可供GatewayFilter工厂spring-doc.cadn.net.cn

实用程序方法(称为get) 可用于更轻松地访问这些变量。 以下示例演示如何使用get方法:spring-doc.cadn.net.cn

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

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

5.9. 查询路由谓词工厂

QueryRoute Predicate Factory 采用两个参数:一个必需的param和可选的regexp(这是一个 Java 正则表达式)。 以下示例配置查询路由谓词:spring-doc.cadn.net.cn

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

如果请求包含greenquery 参数。spring-doc.cadn.net.cn

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

如果请求包含redquery 参数,其值与gree.regexp 的greengreet将匹配。spring-doc.cadn.net.cn

5.10. RemoteAddr 路由谓词工厂

RemoteAddrRoute Predicate Factory 接受sources,它们是 CIDR 表示法(IPv4 或 IPv6)字符串,例如192.168.0.1/16(其中192.168.0.1是 IP 地址,而16是子网掩码)。 下面的示例配置 RemoteAddr 路由谓词:spring-doc.cadn.net.cn

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

例如,如果请求的远程地址是192.168.1.10.spring-doc.cadn.net.cn

5.10.1. 修改解析远程地址的方式

默认情况下,RemoteAddr 路由谓词工厂使用来自传入请求的远程地址。 如果 Spring Cloud Gateway 位于代理层后面,则这可能与实际的客户端 IP 地址不匹配。spring-doc.cadn.net.cn

您可以通过设置自定义RemoteAddressResolver. Spring Cloud 网关带有一个基于 X-Forwarded-For 标头的非默认远程地址解析器,XForwardedRemoteAddressResolver.spring-doc.cadn.net.cn

XForwardedRemoteAddressResolver有两个 static 构造函数方法,它们采用不同的安全方法:spring-doc.cadn.net.cn

  • XForwardedRemoteAddressResolver::trustAll返回RemoteAddressResolver,它始终采用在X-Forwarded-For页眉。 这种方法容易受到欺骗,因为恶意客户端可能会为X-Forwarded-For,解析程序将接受该 Zip 的 Zip S Package。spring-doc.cadn.net.cn

  • XForwardedRemoteAddressResolver::maxTrustedIndex采用与 Spring Cloud Gateway 前面运行的可信基础设施数量相关的索引。 例如,如果 Spring Cloud 网关只能通过 HAProxy 访问,则应使用值 1。 如果在 Spring Cloud Gateway 可访问之前需要两个受信任的基础结构跃点,则应使用值 2。spring-doc.cadn.net.cn

请考虑以下标头值:spring-doc.cadn.net.cn

X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3

以下内容maxTrustedIndex值生成以下远程地址:spring-doc.cadn.net.cn

maxTrustedIndex 结果

[Integer.MIN_VALUE,0]spring-doc.cadn.net.cn

(无效,IllegalArgumentException在初始化期间)spring-doc.cadn.net.cn

1spring-doc.cadn.net.cn

0.0.0.3spring-doc.cadn.net.cn

2spring-doc.cadn.net.cn

0.0.0.2spring-doc.cadn.net.cn

3spring-doc.cadn.net.cn

0.0.0.1spring-doc.cadn.net.cn

[4,Integer.MAX_VALUE]spring-doc.cadn.net.cn

0.0.0.1spring-doc.cadn.net.cn

以下示例显示了如何使用 Java 实现相同的配置:spring-doc.cadn.net.cn

例 11.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")
)

5.11. 权重路由谓词工厂

WeightRoute Predicate Factory 接受两个参数:groupweight(一个 int)。权重按组计算。 以下示例配置权重路由谓词:spring-doc.cadn.net.cn

例 12.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% 的流量转发到 weighlow.orgspring-doc.cadn.net.cn

5.12. XForwarded 远程 Addr 路由谓词工厂

XForwarded Remote AddrRoute Predicate Factory 接受sources,它们是 CIDR 表示法(IPv4 或 IPv6)字符串,例如192.168.0.1/16(其中192.168.0.1是 IP 地址,而16是子网掩码)。spring-doc.cadn.net.cn

此路由谓词允许根据X-Forwarded-ForHTTP 标头。spring-doc.cadn.net.cn

这可以与反向代理(如负载均衡器或 Web 应用程序防火墙)一起使用,其中 仅当请求来自这些地址使用的受信任 IP 地址列表时,才应允许该请求 反向代理。spring-doc.cadn.net.cn

下面的示例配置 XForwardedRemoteAddr 路由谓词:spring-doc.cadn.net.cn

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

如果X-Forwarded-Forheader 包含,例如192.168.1.10.spring-doc.cadn.net.cn