程序员L札记

V1

2022/04/18阅读:28主题:橙心

最新Spring Cloud Gateway中文文档(一)

spring cloud gateway版本3.1.1


配置路由谓词工厂和网关过滤工厂

有两种配置谓词和过滤器的方法:快捷方式和完全扩展的参数。下面的大多数例子都使用了快捷方式。

名称和参数名称将作为代码列在每个部分的第一句或第二句中。参数通常按快捷方式配置所需的顺序列出。

快捷方式配置

快捷方式配置由过滤器名称识别,后跟等号 (=),后跟以逗号 (,) 分隔的参数值

application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - Cookie=mycookie,mycookievalue

前面的示例使用两个参数定义了 Cookie 路由谓词工厂,即 cookie 名称、mycookie 和匹配 mycookievalue 的值。

完全展开的参数

完全扩展的参数看起来更像是带有名称/值对的标准 yaml 配置。通常,会有一个 name 键和一个 args 键。 args 键是用于配置谓词或过滤器的键值对映射

application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - name: Cookie
          args:
            name: mycookie
            regexp: mycookievalue

这是上面显示的 Cookie 谓词的快捷方式配置的完整配置。

路由谓词工厂

Spring Cloud Gateway 将路由匹配为 Spring WebFlux HandlerMapping 基础设施的一部分。 Spring Cloud Gateway 包含许多内置的路由谓词工厂。所有这些谓词都匹配 HTTP 请求的不同属性。您可以将多个路由谓词工厂与逻辑和语句结合起来。

AfterRoutePredicateFactory

After路由谓词工厂接受一个参数,一个datetime(它是一个java ZonedDateTime)。此谓词匹配发生在指定日期时间之后的请求。配置after路由谓词的示例如下:

Example 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 Mountain Time(丹佛)之后提出的任何请求

BeforeRoutePredicateFactory

Before路由谓词工厂接受一个参数,一个datetime(它是一个java ZonedDateTime)。此谓词匹配发生在指定日期时间之前的请求。配置前置路由谓词的示例如下:

Example 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 Mountain Time (Denver) 之前提出的任何请求相匹配。

BetweenRoutePredicateFactory

Between路由谓词工厂接受两个参数,datetime1和datetime2,它们是java ZonedDateTime对象。这个谓词匹配发生在datetime1之后和datetime2之前的请求。datetime2必须在datetime1之后。下面的例子配置了一个路由谓词:

Example 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 山区时间(丹佛)之前提出的任何请求。这对于维护窗口可能很有用

CookieRoutePredicateFactory

Cookie 路由谓词工厂有两个参数,cookie name和一个regexp(它是一个 Java 正则表达式)。此谓词匹配具有给定名称且其值与正则表达式匹配的 cookie。以下示例配置 cookie 路由谓词工厂:

Example 4. application.yml

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

此路由将匹配具有一个cookie名为chocolate的的请求,该cookie的值匹配ch.p正则表达式。

HeaderRoutePredicateFactory

Header路由谓词工厂接受两个参数,header和regexp(它是一个Java正则表达式)。该谓词与具有给定名称的头匹配,该名称的值与正则表达式匹配。下面的例子配置了报头路由谓词:

Example 5. application.yml

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

如果请求有一个名为X-Request-Id的头,其值匹配\d+正则表达式(也就是说,它有一个或多个数字的值),则此路由匹配。

HostRoutePredicateFactory

Host路由谓词工厂接受一个参数:主机名patterns列表。该模式是一个ant风格的模式,使用.作为分隔符。此谓词匹配与模式匹配的 Host 请求头。配置主机路由谓词的示例如下:

Example 6. 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.org或beta.somehost.org或www.anotherhost.org,则此路由匹配。

此谓词将 URI 模板变量(例如,在前面的示例中定义的 sub)提取为名称和值的映射,并将其放置在 ServerWebExchange.getAttributes() 中,并使用在 ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE 中定义的键。然后这些值可供 GatewayFilter 工厂使用

MethodRoutePredicateFactory

方法路由谓词工厂接受一个methods参数,该参数是一个或多个参数:要匹配的 HTTP 方法。以下示例配置方法路由谓词:

Example 7. application.yml

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

如果请求方法是 GET 或 POST,则此路由匹配。

PathRoutePredicateFactory

Path Route Predicate Factory 有两个参数:一个 Spring PathMatcher patterns列表和一个名为 matchTrailingSlash 的可选标志(默认为 true)。以下示例配置路径路由谓词:

Example 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。

如果matchTrailingSlash设置为false,那么请求路径/red/1/将不会被匹配。

此谓词将 URI 模板变量(例如,在前面的示例中定义的segment)提取为名称和值的映射,并将其放置在 ServerWebExchange.getAttributes() 中,并使用在 ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE 中定义的键。然后这些值可供 GatewayFilter 工厂使用

可以使用一个实用方法(调用get)来简化对这些变量的访问。下面的例子展示了如何使用get方法:

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

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

QueryRoutePredicateFactory

Query路由谓词工厂接受两个参数:一个必需的param和一个可选的regexp(它是一个Java正则表达式)。下面的例子配置了一个查询路由谓词:

Example 9. 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.正则表达式,则上述路由匹配。所以green和greet是匹配的。

RemoteAddrRoutePredicateFactory

RemoteAddr路由谓词工厂接受一个sources列表(最小大小为1),它是cidr表示法(IPv4或IPv6)字符串,例如192.168.0.1/16(其中192.168.0.1是一个IP地址,16是一个子网掩码)。配置RemoteAddr路由谓词的示例如下:

Example 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,则此路由匹配。

修改远程地址的解析方式

默认情况下,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 result
[Integer.MIN_VALUE,0] (invalid, IllegalArgumentException during initialization)
1 0.0.0.3
2 0.0.0.2
3 0.0.0.1
[4, Integer.MAX_VALUE] 0.0.0.1

以下示例显示了如何使用 Java 实现相同的配置:

Example 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")
)

WeightRoutePredicateFactory

权重路由谓词工厂有两个参数:group和weight(一个 int)。权重是按组计算的。以下示例配置权重路由谓词:

Example 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% 的流量转发到 weightlow.org

XForwardedRemoteAddrRoutePredicateFactory

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 路由谓词:

Example 13. 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,则此路由匹配。

欢迎关注我的公众号:程序员L札记

更多原创文章,请扫码关注我的微信公众号
更多原创文章,请扫码关注我的微信公众号

分类:

后端

标签:

Java

作者介绍

程序员L札记
V1