5. 路由谓词工厂
Spring Cloud 网关将路由作为 Spring WebFlux 基础结构的一部分进行匹配。
Spring Cloud 网关包括许多内置的路由谓词工厂。
所有这些谓词都与 HTTP 请求的不同属性匹配。
您可以将多个路由谓词工厂与逻辑语句组合在一起。HandlerMapping
and
5.1. After Route 谓词工厂
路由谓词工厂采用一个参数 a (即 java )。
此谓词匹配在指定日期/时间之后发生的请求。
以下示例配置 after 路由谓词:After
datetime
ZonedDateTime
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 山区时间(丹佛)之后发出的任何请求。
5.2. Before Route 谓词工厂
路由谓词工厂采用一个参数 a (即 java )。
此谓词匹配在指定的 .
以下示例配置 before route 谓词:Before
datetime
ZonedDateTime
datetime
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 山区时间(丹佛)之前发出的任何请求。
5.3. Between 路由谓词工厂
路由谓词工厂采用两个参数,它们是 java 对象。
此谓词匹配在 之后和之前发生的请求。
参数必须位于 之后。
以下示例配置了 between 路由谓词:Between
datetime1
datetime2
ZonedDateTime
datetime1
datetime2
datetime2
datetime1
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 山区时间(丹佛)之前发出的任何请求。 这对于维护时段可能很有用。
5.4. Cookie 路由谓词工厂
路由谓词工厂采用两个参数:cookie 和 a(这是一个 Java 正则表达式)。
此谓词匹配具有给定名称且其值与正则表达式匹配的 Cookie。
以下示例配置 cookie 路由谓词工厂:Cookie
name
regexp
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
此路由匹配具有 cookie 的请求,该 cookie 的名称与其值与正则表达式匹配。chocolate
ch.p
5.5. Header 路由谓词工厂
路由谓词工厂采用两个参数,即 the 和 a(这是一个 Java 正则表达式)。
此谓词与具有给定名称的 Headers 匹配,该 Headers 的值与正则表达式匹配。
以下示例配置标头路由谓词:Header
header
regexp
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
如果请求具有一个名为 Headers 的 Header,其值与正则表达式匹配(即,它的值为一个或多个数字),则此路由匹配。X-Request-Id
\d+
5.6. 主机路由谓词工厂
路由谓词工厂采用一个参数: host name 列表。
该模式是 Ant 样式的模式,作为分隔符。
此谓词与匹配模式的标头匹配。
以下示例配置主机路由谓词:Host
patterns
.
Host
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
还支持 URI 模板变量(如 )。{sub}.myhost.org
如果请求的标头值为 or 或 ,则此路由匹配。Host
www.somehost.org
beta.somehost.org
www.anotherhost.org
此谓词将 URI 模板变量(如上例中定义的 )提取为名称和值的映射,并将其放置在 中,并在 中定义了键。
然后,这些值可供 GatewayFilter
工厂使用sub
ServerWebExchange.getAttributes()
ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
5.7. Method Route Predicate Factory
Route Predicate Factory 采用一个参数,该参数是一个或多个参数:要匹配的 HTTP 方法。
以下示例配置方法路由谓词:Method
methods
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
如果请求方法是 a 或 a ,则此路由匹配。GET
POST
5.8. 路径路由谓词工厂
Route Predicate Factory 采用两个参数:Spring 列表和名为 (defaults to) 的可选标志。
以下示例配置路径路由谓词:Path
PathMatcher
patterns
matchTrailingSlash
true
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
如果请求路径为,则此路由匹配,例如:or or or 。/red/1
/red/1/
/red/blue
/blue/green
如果设置为 ,则不会匹配请求路径。matchTrailingSlash
false
/red/1/
此谓词将 URI 模板变量(如上例中定义的 )提取为名称和值的映射,并将其放置在 中,并在 中定义了键。
然后,这些值可供 GatewayFilter
工厂使用segment
ServerWebExchange.getAttributes()
ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
可以使用一种实用程序方法(称为 )来更轻松地访问这些变量。
以下示例演示如何使用该方法:get
get
Map<String, String> uriVariables = ServerWebExchangeUtils.getUriTemplateVariables(exchange);
String segment = uriVariables.get("segment");
5.9. 查询路由谓词工厂
路由谓词工厂采用两个参数:一个 required 和一个 optional (这是一个 Java 正则表达式)。
以下示例配置查询路由谓词:Query
param
regexp
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
如果请求包含查询参数,则前面的路由匹配。green
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree.
如果请求包含其值与 regexp 匹配的查询参数,则前面的路由匹配,则 so 和 would match。red
gree.
green
greet
5.10. RemoteAddr 路由谓词工厂
路由谓词工厂采用 的列表(最小大小 1),这些列表是 CIDR 表示法(IPv4 或 IPv6)字符串,例如(其中 是 IP 地址,是子网掩码)。
下面的示例配置 RemoteAddr 路由谓词:RemoteAddr
sources
192.168.0.1/16
192.168.0.1
16
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
例如,如果请求的远程地址为 .192.168.1.10
5.10.1. 修改解析远程地址的方式
默认情况下,RemoteAddr 路由谓词工厂使用来自传入请求的远程地址。 如果 Spring Cloud Gateway 位于代理层后面,则这可能与实际的客户端 IP 地址不匹配。
您可以通过设置自定义 .
Spring Cloud 网关附带一个基于 X-Forwarded-For 标头的非默认远程地址解析器。RemoteAddressResolver
XForwardedRemoteAddressResolver
XForwardedRemoteAddressResolver
有两个 static 构造函数方法,它们采用不同的安全方法:
-
XForwardedRemoteAddressResolver::trustAll
返回 a,它始终采用在标头中找到的第一个 IP 地址。 此方法容易受到欺骗,因为恶意客户端可能会为 设置初始值,解析程序将接受该值。RemoteAddressResolver
X-Forwarded-For
X-Forwarded-For
-
XForwardedRemoteAddressResolver::maxTrustedIndex
采用与 Spring Cloud Gateway 前面运行的可信基础设施数量相关的索引。 例如,如果 Spring Cloud 网关只能通过 HAProxy 访问,则应使用值 1。 如果在 Spring Cloud Gateway 可访问之前需要两个受信任的基础结构跃点,则应使用值 2。
请考虑以下标头值:
X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3
以下值生成以下远程地址:maxTrustedIndex
maxTrustedIndex |
结果 |
---|---|
[ |
(无效,在初始化期间) |
1 |
0.0.0.3 |
2 |
0.0.0.2 |
3 |
0.0.0.1 |
[4, |
0.0.0.1 |
以下示例显示了如何使用 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. 权重路由谓词工厂
路由谓词工厂接受两个参数:和 (an int)。权重按组计算。
以下示例配置权重路由谓词:Weight
group
weight
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.org
5.12. XForwarded 远程 Addr 路由谓词工厂
路由谓词工厂采用 的列表(最小大小 1),这些列表是 CIDR 表示法(IPv4 或 IPv6)字符串,例如(其中 是 IP 地址,是子网掩码)。XForwarded Remote Addr
sources
192.168.0.1/16
192.168.0.1
16
此路由谓词允许根据 HTTP 标头筛选请求。X-Forwarded-For
这可以与反向代理(如负载均衡器或 Web 应用程序防火墙)一起使用,其中 仅当请求来自这些地址使用的受信任 IP 地址列表时,才应允许该请求 反向代理。
下面的示例配置 XForwardedRemoteAddr 路由谓词:
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