On this page
114. Route 谓词工厂
Spring Cloud Gateway 将路由作为 Spring WebFlux HandlerMapping
基础架构的一部分进行匹配。 Spring Cloud Gateway 包括许多内置的 Route Predicate 工厂。所有这些谓词都与 HTTP 请求的不同属性匹配。多个路由谓词工厂可以组合,并通过逻辑and
进行组合。
114.1 Route Predicate Factory 之后
路由后谓词工厂采用一个参数,即日期时间。该谓词匹配在当前日期时间之后发生的请求。
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 山区时间(丹佛)之后的所有请求匹配。
114.2 Route Predicate Factory 之前
路由谓词前工厂采用一个参数,即日期时间。该谓词匹配当前日期时间之前发生的请求。
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 山区时间(丹佛)之前的所有请求匹配。
114.3 路由谓词工厂之间
路由谓词间工厂之间采用两个参数 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]
此 Route 与 2017 年 1 月 20 日山区时间(丹佛)之后和 2017 年 1 月 21 日 17:42 山时间(丹佛)之后的任何请求匹配。这对于维护时段可能很有用。
114.4 CookieRoute 谓词工厂
Cookie Route Predicate Factory 采用两个参数,即 cookie 名称和正则表达式。该谓词匹配具有给定名称的 cookie,并且值匹配正则表达式。
application.yml.
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://example.org
predicates:
- Cookie=chocolate, ch.p
此路由与请求匹配,并具有一个名为chocolate
的 cookie,该 cookie 的值与ch.p
正则表达式匹配。
114.5Headers 路由谓词工厂
Headers 路由谓词工厂采用两个参数,Headers 名称和正则表达式。该谓词与具有给定名称的 Headers 匹配,并且值与正则表达式匹配。
application.yml.
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://example.org
predicates:
- Header=X-Request-Id, \d+
如果请求的标题为X-Request-Id
,而其值与\d+
正则表达式匹配(具有一个或多个数字的值),则此路由匹配。
114.6 主机路由谓词工厂
主机路由谓词工厂采用一个参数:主机名模式列表。该模式是以.
作为分隔符的 Ant 样式模式。该谓词匹配与模式匹配的Host
Headers。
application.yml.
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
还支持 URI 模板变量,例如{sub}.myhost.org
。
如果请求的Host
Headers 的值为www.somehost.org
或beta.somehost.org
或www.anotherhost.org
,则此路由将匹配。
该谓词提取 URI 模板变量(如上例中定义的sub
)作为名称和值的 Map,并使用ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
中定义的键将其放在ServerWebExchange.getAttributes()
中。这些值随后可供GatewayFilter Factories使用
114.7 方法 Route 谓词工厂
方法路由谓词工厂使用一个参数:要匹配的 HTTP 方法。
application.yml.
spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://example.org
predicates:
- Method=GET
如果请求方法是GET
,则此路由将匹配。
114.8 路径路由谓词工厂
路径路由谓词工厂采用两个参数:Spring PathMatcher
模式列表和matchOptionalTrailingSeparator
的可选标志。
application.yml.
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://example.org
predicates:
- Path=/foo/{segment},/bar/{segment}
如果请求路径为/foo/1
或/foo/bar
或/bar/baz
,则此路由将匹配。
该谓词提取 URI 模板变量(如上例中定义的segment
)作为名称和值的 Map,并使用ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
中定义的键将其放在ServerWebExchange.getAttributes()
中。这些值随后可供GatewayFilter Factories使用
可以使用 Util 方法来简化对这些变量的访问。
Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
String segment = uriVariables.get("segment");
114.9 查询路由谓词工厂
查询路由谓词工厂采用两个参数:必需的param
和可选的regexp
。
application.yml.
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://example.org
predicates:
- Query=baz
如果请求包含baz
查询参数,则此路由将匹配。
application.yml.
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://example.org
predicates:
- Query=foo, ba.
如果请求包含一个foo
查询参数,其值与ba.
正则表达式匹配,则此路由将匹配,因此bar
和baz
将匹配。
114.10 RemoteAddr 路由谓词工厂
RemoteAddr 路由谓词工厂采用 CIDR 标记(IPv4 或 IPv6)字符串的列表(最小大小为 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
如果请求的远程地址为192.168.1.10
,则此路由将匹配。
114.10.1 修改解析远程地址的方式
默认情况下,RemoteAddr 路由谓词工厂使用传入请求中的远程地址。如果 Spring Cloud Gateway 位于代理层后面,则此地址可能与实际的 Client 端 IP 地址不匹配。
您可以通过设置自定义RemoteAddressResolver
来定制解析远程地址的方式。 Spring Cloud Gateway 随附了一个基于X-Forwarded-For header,XForwardedRemoteAddressResolver
的非默认远程地址解析器。
XForwardedRemoteAddressResolver
有两种静态构造方法,它们采用不同的安全性方法:
XForwardedRemoteAddressResolver::trustAll
返回一个RemoteAddressResolver
,该RemoteAddressResolver
始终采用X-Forwarded-For
Headers 中找到的第一个 IP 地址。这种方法容易受到欺骗的攻击,因为恶意 Client 端可能会为X-Forwarded-For
设置初始值,解析器会接受该初始值。
XForwardedRemoteAddressResolver::maxTrustedIndex
取得一个索引,该索引与 Spring Cloud Gateway 前面运行的受信任基础结构的数量相关。例如,如果只能通过 HAProxy 访问 Spring Cloud Gateway,则应使用值 1.如果在访问 Spring Cloud Gateway 之前需要两跳可信基础架构,则应使用值 2.
给定以下 Headers 值:
X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3
下面的maxTrustedIndex
值将产生以下远程地址。
maxTrustedIndex |
result |
---|---|
[ 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 |
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")
)