Spring Cloud Gateway(网关)

Spring Cloud Gateway(网关)

该项目提供了一个建立在 Spring 生态系统之上的 API 网关,包括:Spring 5、Spring Boot 2 和 Project Reactor。Spring Cloud Gateway旨在提供一种简单而有效的方法来路由到API,并为它们提供跨领域关注点,例如:安全性,监控/指标和弹性。

1. 如何包含弹簧云网关

要在项目中包含 Spring Cloud Gateway,请使用组 ID 为 和工件 ID 为 的启动器。 有关使用当前 Spring 云发布系列设置构建系统的详细信息,请参阅Spring 云项目页面。​​org.springframework.cloud​​​​spring-cloud-starter-gateway​

如果包括启动器,但不希望启用网关,请设置。​​spring.cloud.gateway.enabled=false​

Spring Cloud Gateway 建立在Spring Boot 2.x、Spring WebFlux​ 和Project Reactor 之上。 因此,当您使用 Spring Cloud Gateway 时,您知道的许多熟悉的同步库(例如 Spring 数据和 Spring 安全性)和模式可能不适用。 如果您不熟悉这些项目,我们建议您在使用Spring Cloud Gateway之前先阅读他们的文档以熟悉一些新概念。

Spring Cloud Gateway 需要 Spring Boot 和 Spring Webflux 提供的 Netty 运行时。 它不适用于传统的 Servlet 容器或作为 WAR 构建时。

2. 词汇表

  • 路由:网关的基本构建基块。 它由 ID、目标 URI、谓词集合和筛选器集合定义。如果聚合谓词为 true,则匹配路由。
  • 谓词:这是一个Java 8函数谓词。输入类型是Spring FrameworkServerWebExchange。 这使您可以匹配 HTTP 请求中的任何内容,例如标头或参数。
  • ​筛选器:这些是使用特定工厂构造的网关筛选器实例。 在这里,您可以在发送下游请求之前或之后修改请求和响应。

3. 工作原理

下图提供了 Spring 云网关工作原理的高级概述:

Spring Cloud Gateway(网关)

客户端向 Spring Cloud 网关发出请求。如果网关处理程序映射确定请求与路由匹配,则会将其发送到网关 Web 处理程序。 此处理程序通过特定于请求的筛选器链运行请求。 筛选器用虚线划分的原因是筛选器可以在发送代理请求之前和之后运行逻辑。 执行所有“预”过滤器逻辑。然后发出代理请求。发出代理请求后,将运行“post”筛选器逻辑。

在没有端口的路由中定义的 URI 分别获取 HTTP 和 HTTPS URI 的默认端口值 80 和 443。

4. 配置路由谓词工厂和网关筛选器工厂

有两种方法可以配置谓词和筛选器:快捷方式和完全展开的参数。下面的大多数示例都使用快捷方式。

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

4.1. 快捷键配置

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

应用程序.yml

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

前面的示例使用两个参数(cookie 名称和要匹配的值)定义路由谓词工厂。​​Cookie​​​​mycookie​​​​mycookievalue​

4.2. 完全展开的参数

完全展开的参数看起来更像是具有名称/值对的标准 yaml 配置。通常,会有akey和ankey。键是用于配置谓词或筛选器的键值对映射。​​name​​​​args​​​​args​

应用程序.yml

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

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

5. 路由谓词工厂

Spring Cloud Gateway将路由匹配为Spring WebFlux基础架构的一部分。 Spring Cloud Gateway 包括许多内置的路由谓词工厂。 所有这些谓词都匹配 HTTP 请求的不同属性。 您可以将多个路由谓词工厂与逻辑语句组合在一起。​​HandlerMapping​​​​and​

5.1. 路由后谓词工厂

路由谓词工厂采用一个参数 a(这是一个 java)。 此谓词匹配在指定日期时间之后发生的请求。 以下示例配置路由后谓词:​​After​​​​datetime​​​​ZonedDateTime​

例 1.应用程序.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 之后提出的任何请求(丹佛)匹配。

5.2. 路由前谓词工厂

路由谓词工厂采用一个参数 a(这是一个 java)。 此谓词匹配在指定之前发生的请求。 以下示例配置路由之前谓词:​​Before​​​​datetime​​​​ZonedDateTime​​​​datetime​

例 2.应用程序.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 (丹佛)之前提出的任何请求匹配。

5.3. 路由谓词工厂

路由谓词工厂有两个参数,分别是java对象。 此谓词匹配之后和之前发生的请求。 参数必须在之后。 以下示例配置路由谓词之间:​​Between​​​​datetime1​​​​datetime2​​​​ZonedDateTime​​​​datetime1​​​​datetime2​​​​datetime2​​​​datetime1​

例 3.应用程序.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(丹佛)之前提出的任何请求匹配。 这对于维护时段可能很有用。

5.4. 饼干路由谓词工厂

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

例 4.应用程序.yml

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

此路由匹配具有名为 cookie 的请求,其值与正则表达式匹配。​​chocolate​​​​ch.p​

5.5. 标头路由谓词工厂

路由谓词工厂有两个参数,theand a(这是一个Java正则表达式)。 此谓词与具有给定名称的标头匹配,该标头的值与正则表达式匹配。 以下示例配置标头路由谓词:​​Header​​​​header​​​​regexp​

例 5.应用程序.yml

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

如果请求具有名为其值与正则表达式匹配的标头(即,它的值为一个或多个数字),则此路由匹配。​​X-Request-Id​​​​d+​

5.6. 主机路由谓词工厂

路由谓词工厂采用一个参数:主机名列表。 该图案是带有分隔符的蚂蚁样式图案。 此谓词匹配与模式匹配的标头。 以下示例配置主机路由谓词:​​Host​​​​patterns​​​​.​​​​Host​

例 6.应用程序.yml

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

还支持 URI 模板变量(例如)。​​{sub}.myhost.org​

如果请求具有值 oforor 的标头,则此路由匹配。​​Host​​​​www.somehost.org​​​​beta.somehost.org​​​​www.anotherhost.org​

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

5.7. 方法路由谓词工厂

TheRoute 谓词工厂采用一个或多个参数的参数:要匹配的 HTTP 方法。 以下示例配置方法路由谓词:​​Method​​​​methods​

例 7.应用程序.yml

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

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

5.8. 路径路由谓词工厂

TheRoute 谓词工厂采用两个参数:一个 Spring 列表和一个调用的可选标志(默认为)。 以下示例配置路径路由谓词:​​Path​​​​PathMatcher​​​​patterns​​​​matchTrailingSlash​​​​true​

例 8.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}

如果请求路径是,例如:ororor,则此路由匹配。​​/red/1​​​​/red/1/​​​​/red/blue​​​​/blue/green​

ifis 设置为,则请求路径将不匹配。​​matchTrailingSlash​​​​false​​​​/red/1/​

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

实用程序方法(调用)可用于更轻松地访问这些变量。 下面的示例演示如何使用该方法:​​get​​​​get​

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

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

5.9. 查询路由谓词工厂

路由谓词工厂采用两个参数:必需参数和可选参数(这是 Java 正则表达式)。 以下示例配置查询路由谓词:​​Query​​​​param​​​​regexp​

例 9.应用程序.yml

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

如果请求包含查询参数,则上述路由匹配。​​green​

应用程序.yml

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

如果请求包含值与 theregexp 匹配的查询参数,则前面的路由匹配。​​red​​​​gree.​​​​green​​​​greet​

5.10. 远程地址路由谓词工厂

路由谓词工厂采用一个列表(最小大小为 1),它们是 CIDR 表示法(IPv4 或 IPv6)字符串,例如(其中 IP 地址和子网掩码)。 下面的示例配置远程添加路由谓词:​​RemoteAddr​​​​sources​​​​192.168.0.1/16​​​​192.168.0.1​​​​16​

例 10.应用程序.yml

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 网关位于代理层后面,这可能与实际的客户端 IP 地址不匹配。

您可以通过设置自定义来自定义远程地址的解析方式。 Spring Cloud Gateway附带一个基于X-Forwarded-For标头的非默认远程地址解析器。​​RemoteAddressResolver​​​​XForwardedRemoteAddressResolver​

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

  • ​XForwardedRemoteAddressResolver::trustAll​​返回 a,始终采用标头中找到的第一个 IP 地址。 此方法容易受到欺骗,因为恶意客户端可能会为 设置一个初始值,解析程序将接受该值。RemoteAddressResolverX-Forwarded-ForX-Forwarded-For
  • ​XForwardedRemoteAddressResolver::maxTrustedIndex​​获取与在 Spring 云网关前面运行的受信任基础架构数量相关的索引。 例如,如果Spring Cloud Gateway只能通过HAProxy访问,则应使用值1。 如果在访问 Spring 云网关之前需要两个受信任基础设施的跃点,则应使用值 2。

请考虑以下标头值:

X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3

以下值生成以下远程地址:​​maxTrustedIndex​

​maxTrustedIndex​

结果

[​​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

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

例 11.网关配置.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. 权重路由谓词工厂

路由谓词工厂采用两个参数:and(一个整数)。权重按组计算。 以下示例配置权重路由谓词:​​Weight​​​​group​​​​weight​

例 12.应用程序.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.org

5.12. 远程地址路由谓词工厂

路由谓词工厂采用一个列表(最小大小为 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 地址使用的受信任 IP 地址列表时,才应允许该请求 反向代理。

下面的示例配置 XForwardedRemoteAddr 路由谓词:

例 13.应用程序.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​

6.网关过滤器工厂

路由筛选器允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。 路由筛选器的作用域为特定路由。 Spring Cloud Gateway 包括许多内置的 GatewayFilter 工厂。

有关如何使用以下任何筛选器的更详细示例,请查看单元测试。

6.1.AddRequestHeader网关过滤器工厂

工厂采取和参数。 以下示例配置:​​AddRequestHeader​​​​GatewayFilter​​​​name​​​​value​​​​AddRequestHeader​​​​GatewayFilter​

例 14.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-red, blue

此清单将标头添加到所有匹配请求的下游请求标头中。​​X-Request-red:blue​

​AddRequestHeader​​知道用于匹配路径或主机的 URI 变量。 URI 变量可以在值中使用,并在运行时展开。 以下示例配置使用变量的 an:​​AddRequestHeader​​​​GatewayFilter​

例 15.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- AddRequestHeader=X-Request-Red, Blue-{segment}

6.2.添加请求参数网关过滤器工厂

工厂采取aand参数。 以下示例配置:​​AddRequestParameter​​​​GatewayFilter​​​​name​​​​value​​​​AddRequestParameter​​​​GatewayFilter​

例 16.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=red, blue

这将添加到所有匹配请求的下游请求的查询字符串中。​​red=blue​

​AddRequestParameter​​知道用于匹配路径或主机的 URI 变量。 URI 变量可以在值中使用,并在运行时展开。 以下示例配置使用变量的 an:​​AddRequestParameter​​​​GatewayFilter​

例 17.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddRequestParameter=foo, bar-{segment}

6.3.AddResponseHeader网关过滤器工厂

工厂采取aand参数。 以下示例配置:​​AddResponseHeader​​​​GatewayFilter​​​​name​​​​value​​​​AddResponseHeader​​​​GatewayFilter​

例 18.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Red, Blue

这会将标头添加到所有匹配请求的下游响应标头中。​​X-Response-Red:Blue​

​AddResponseHeader​​知道用于匹配路径或主机的 URI 变量。 URI 变量可以在值中使用,并在运行时展开。 以下示例配置使用变量的 an:​​AddResponseHeader​​​​GatewayFilter​

例 19.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddResponseHeader=foo, bar-{segment}

6.4.重复数据删除响应标头网关过滤器工厂

DedupeResponseHeader GatewayFilter 工厂采用参数和可选参数。可以包含以空格分隔的标头名称列表。 以下示例配置:​​name​​​​strategy​​​​name​​​​DedupeResponseHeader​​​​GatewayFilter​

例 20.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: dedupe_response_header_route
uri: https://example.org
filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

这会在网关 CORS 逻辑和下游逻辑都添加重复值的情况下删除重复值和响应标头。​​Access-Control-Allow-Credentials​​​​Access-Control-Allow-Origin​

筛选器还接受可选参数。 接受的值为(默认值)、和。​​DedupeResponseHeader​​​​strategy​​​​RETAIN_FIRST​​​​RETAIN_LAST​​​​RETAIN_UNIQUE​

6.5. 弹簧云断路器网关过滤器工厂

Spring Cloud Breaker GatewayFilter 工厂使用 Spring Cloud Breaker API 将网关路由包装在 断路器。Spring Cloud Breaker支持多个可与Spring Cloud Gateway一起使用的库。Spring Cloud 支持开箱即用的 Resilience4J。

要启用 Spring Cloud Breaker 筛选器,您需要放置在类路径上。 以下示例配置了一个 Spring Cloud Breaker:​​spring-cloud-starter-circuitbreaker-reactor-resilience4j​​​​GatewayFilter​

例 21.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: https://example.org
filters:
- CircuitBreaker=myCircuitBreaker

若要配置断路器,请参阅正在使用的基础断路器实现的配置。

  • 弹性4J文档

Spring Cloud Breaker 筛选器也可以接受可选参数。 目前,仅支持方案 URI。 如果调用回退,则请求将转发到 URI 匹配的控制器。 以下示例配置此类回退:​​fallbackUri​​​​forward:​

例 22.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingServiceEndpoint
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis
- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint

下面的清单在 Java 中执行相同的操作:

例 23。应用.java

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
.filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis"))
.rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
.build();
}

此示例在调用断路器回退时转发到 URI。 请注意,此示例还演示了(可选)Spring Cloud LoadBalancer 负载平衡(由目标 URI 上的前缀定义)。​​/inCaseofFailureUseThis​​​​lb​

主要方案是使用 the在网关应用程序中定义内部控制器或处理程序。 但是,您也可以将请求重新路由到外部应用程序中的控制器或处理程序,如下所示:​​fallbackUri​

例 24.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: CircuitBreaker
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback

在此示例中,网关应用程序中没有终结点或处理程序。 但是,在另一个应用程序中有一个,注册下。​​fallback​​​​localhost:9994​

如果请求被转发到回退,Spring Cloud Breaker 网关筛选器还提供导致它的原因。 它被添加到属性中,可以在处理网关应用程序中的回退时使用。​​Throwable​​​​ServerWebExchange​​​​ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR​

对于外部控制器/处理程序方案,可以添加包含异常详细信息的标头。 可以在回退标头网关筛选器工厂部分找到有关执行此操作的详细信息。

6.5.1. 在状态代码上跳闸断路器

在某些情况下,您可能希望根据状态代码跳闸断路器 从它包装的路由返回。断路器配置对象采用 状态代码,如果返回将导致断路器跳闸。设置 要跳闸断路器的状态代码 您可以使用带有状态代码的整数 值或枚举的字符串表示形式。​​HttpStatus​

例 25.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingServiceEndpoint
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis
statusCodes:
- 500
- "NOT_FOUND"

例 26。应用.java

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
.filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis").addStatusCode("INTERNAL_SERVER_ERROR"))
.rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
.build();
}

6.6.回退头网关过滤器工厂

Thefactory 允许您在转发到外部应用程序的请求的标头中添加 Spring Cloud Breaker 执行异常详细信息,如以下场景所示:​​FallbackHeaders​​​​fallbackUri​

例 27.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: CircuitBreaker
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
filters:
- name: FallbackHeaders
args:
executionExceptionTypeHeaderName: Test-Header

在此示例中,在运行断路器时发生执行异常后,请求将转发到运行 的应用程序中的终结点或处理程序。 具有异常类型、消息和(如果可用)根本原因异常类型和消息的标头由过滤器添加到该请求中。​​fallback​​​​localhost:9994​​​​FallbackHeaders​

您可以通过设置以下参数的值(以默认值显示)来覆盖配置中标头的名称:

  • ​executionExceptionTypeHeaderName​​ ("Execution-Exception-Type")
  • ​executionExceptionMessageHeaderName​​ ("Execution-Exception-Message")
  • ​rootCauseExceptionTypeHeaderName​​ ("Root-Cause-Exception-Type")
  • ​rootCauseExceptionMessageHeaderName​​ ("Root-Cause-Exception-Message")

有关断路器和网关的详细信息,请参阅Spring Cloud 断路器工厂部分。

6.7.地图请求头网关过滤器工厂

工厂采取沙子参数。 它创建一个新的命名标头 (),并从传入的 http 请求中的现有命名标头 () 中提取该值。 如果输入标头不存在,则筛选器没有影响。 如果新的命名标头已存在,则其值将使用新值进行扩充。 以下示例配置:​​MapRequestHeader​​​​GatewayFilter​​​​fromHeader​​​​toHeader​​​​toHeader​​​​fromHeader​​​​MapRequestHeader​

例 28.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Blue, X-Request-Red

这会将标头添加到下游请求中,其中包含来自传入 HTTP 请求标头的更新值。​​X-Request-Red:<values>​​​​Blue​

6.8.前缀路径网关过滤器工厂

工厂采用单个参数。 以下示例配置:​​PrefixPath​​​​GatewayFilter​​​​prefix​​​​PrefixPath​​​​GatewayFilter​

例 29.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath

这将以所有匹配请求的路径为前缀。 因此,请求将被发送到。​​/mypath​​​​/hello​​​​/mypath/hello​

6.9.保留主机标头网关过滤器工厂

工厂没有参数。 此筛选器设置路由筛选器检查的请求属性,以确定是否应发送原始主机标头,而不是由 HTTP 客户端确定的主机标头。 以下示例配置:​​PreserveHostHeader​​​​GatewayFilter​​​​PreserveHostHeader​​​​GatewayFilter​

例 30.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader

6.10.请求速率限制器网关过滤器工厂

工厂使用实现来确定是否允许当前请求继续。如果不是,则返回状态(默认情况下)。​​RequestRateLimiter​​​​GatewayFilter​​​​RateLimiter​​​​HTTP 429 - Too Many Requests​

此筛选器采用可选参数和特定于速率限制器的参数(本节稍后将介绍)。​​keyResolver​

​keyResolver​​是实现接口的 bean。 在配置中,使用引用命名 Bean 的 SpEL 表达式 SpEL.is 按名称引用 Bean。 以下清单显示了界面:​​KeyResolver​​​​#{@myKeyResolver}​​​​myKeyResolver​​​​KeyResolver​

例 31。密钥解析程序.java

public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}

该接口允许可插拔策略派生用于限制请求的密钥。 在未来的里程碑版本中,将有一些实现。​​KeyResolver​​​​KeyResolver​

的默认实现是,它从和调用中检索。​​KeyResolver​​​​PrincipalNameKeyResolver​​​​Principal​​​​ServerWebExchange​​​​Principal.getName()​

默认情况下,如果找不到密钥,则拒绝请求。 您可以通过设置 (或) 和属性来调整此行为。​​KeyResolver​​​​spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key​​​​true​​​​false​​​​spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code​

无法使用“快捷方式”表示法进行配置。以下示例无效:​​RequestRateLimiter​

例 32。应用程序属性

# INVALID SHORTCUT CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}

6.10.1. Redis速率限制器

Redis 的实现基于Stripe 所做的工作。 它需要使用Spring Boot启动器。​​spring-boot-starter-data-redis-reactive​

使用的算法是令牌桶算法。

属性是您希望允许用户每秒执行的请求数,而不会丢弃任何请求。 这是填充令牌桶的速率。​​redis-rate-limiter.replenishRate​

属性是允许用户在一秒钟内执行的最大请求数。 这是令牌存储桶可以容纳的令牌数。 将此值设置为零会阻止所有请求。​​redis-rate-limiter.burstCapacity​

属性是请求的成本是多少个令牌。 这是每个请求从存储桶中获取的令牌数,默认为。​​redis-rate-limiter.requestedTokens​​​​1​

通过设置相同的值 inand 来实现稳定的速率。 可以通过设置高于来允许临时突发。 在这种情况下,需要在突发之间允许速率限制器一段时间(根据),因为连续两次突发将导致请求丢弃()。 以下清单配置:​​replenishRate​​​​burstCapacity​​​​burstCapacity​​​​replenishRate​​​​replenishRate​​​​HTTP 429 - Too Many Requests​​​​redis-rate-limiter​

下面的速率限制是通过设置为所需的请求数,以秒为单位的时间跨度和与的乘积(例如设置)来实现的,并且将导致限制。​​1 request/s​​​​replenishRate​​​​requestedTokens​​​​burstCapacity​​​​replenishRate​​​​requestedTokens​​​​replenishRate=1​​​​requestedTokens=60​​​​burstCapacity=60​​​​1 request/min​

例 33.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1

以下示例在 Java 中配置密钥解析程序:

例 34。配置.java

@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}

这定义了每个用户 10 个的请求速率限制。允许突发 20 个,但在下一秒,只有 10 个请求可用。 这是一个获取请求参数的简单方法(请注意,不建议将其用于生产)。​​KeyResolver​​​​user​

您还可以将速率限制器定义为实现接口的 Bean。 在配置中,您可以使用引用 named Bean 的 SpEL 表达式按名称 SpEL.is 引用 Bean。 下面的清单定义了一个速率限制器,该限制器使用在前面的清单中定义的:​​RateLimiter​​​​#{@myRateLimiter}​​​​myRateLimiter​​​​KeyResolver​

例 35.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}"
key-resolver: "#{@userKeyResolver}"

6.11.重定向到网关过滤器工厂

工厂采用两个参数,并且。 参数应为 300 系列重定向 HTTP 代码,例如 301。 参数应为有效的 URL。 这是标头的值。 对于相对重定向,应将路由定义的 uri 用作 URI。 以下清单配置:​​RedirectTo​​​​GatewayFilter​​​​status​​​​url​​​​status​​​​url​​​​Location​​​​uri: no://op​​​​RedirectTo​​​​GatewayFilter​

例 36.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org

这将发送带有标头的状态 302 以执行重定向。​​Location:https://acme.org​

6.12.删除请求标头网关过滤器工厂

工厂采取参数。 它是要删除的标头的名称。 以下清单配置:​​RemoveRequestHeader​​​​GatewayFilter​​​​name​​​​RemoveRequestHeader​​​​GatewayFilter​

例 37.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo

这会在标头发送到下游之前将其删除。​​X-Request-Foo​

6.13.删除响应标头网关筛选器工厂

工厂采取参数。 它是要删除的标头的名称。 以下清单配置:​​RemoveResponseHeader​​​​GatewayFilter​​​​name​​​​RemoveResponseHeader​​​​GatewayFilter​

例 38.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: https://example.org
filters:
- RemoveResponseHeader=X-Response-Foo

这将在响应返回到网关客户端之前从响应中删除标头。​​X-Response-Foo​

若要删除任何类型的敏感标头,应为可能需要配置的任何路由配置此筛选器。 此外,您可以使用此过滤器配置一次,并将其应用于所有路由。​​spring.cloud.gateway.default-filters​

6.14.删除请求参数网关过滤器工厂

工厂采取参数。 它是要删除的查询参数的名称。 以下示例配置:​​RemoveRequestParameter​​​​GatewayFilter​​​​name​​​​RemoveRequestParameter​​​​GatewayFilter​

例 39.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route
uri: https://example.org
filters:
- RemoveRequestParameter=red

这将在将参数发送到下游之前将其删除。​​red​

6.15.请求标头大小网关筛选器工厂

工厂采取沙子参数。 参数是请求标头允许的最大数据大小(包括键和值)。该参数设置包含错误消息的响应标头的名称,默认情况下为“错误消息”。 以下清单配置:​​RequestHeaderSize​​​​GatewayFilter​​​​maxSize​​​​errorHeaderName​​​​maxSize​​​​errorHeaderName​​​​RequestHeaderSize​​​​GatewayFilter​

例 40.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: requestheadersize_route
uri: https://example.org
filters:
- RequestHeaderSize=1000B

如果任何请求标头的大小大于 1000 字节,这将发送状态 431。

6.16.重写路径网关过滤器工厂

工厂采用路径参数和参数。 这使用 Java 正则表达式以灵活的方式重写请求路径。 以下清单配置:​​RewritePath​​​​GatewayFilter​​​​regexp​​​​replacement​​​​RewritePath​​​​GatewayFilter​

例 41.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/red/**
filters:
- RewritePath=/red/?(?<segment>.*), /${segment}

对于请求路径,这会在发出下游请求之前将路径设置为。请注意,由于 YAML 规范,应替换为。​​/red/blue​​​​/blue​​​​$​​​​$​

6.17.重写位置响应标头网关筛选器工厂

工厂修改响应标头的值,通常是为了摆脱特定于后端的详细信息。 它需要,,,和参数。 以下清单配置:​​RewriteLocationResponseHeader​​​​GatewayFilter​​​​Location​​​​stripVersionMode​​​​locationHeaderName​​​​hostValue​​​​protocolsRegex​​​​RewriteLocationResponseHeader​​​​GatewayFilter​

例 42.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: rewritelocationresponseheader_route
uri: http://example.org
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,

例如,对于请求,响应标头值 的被重写为。​​POST api.example.com/some/object/name​​​​Location​​​​object-service.prod.example.net/v2/some/object/id​​​​api.example.com/some/object/id​

参数具有以下可能的值:,(默认值)和。​​stripVersionMode​​​​NEVER_STRIP​​​​AS_IN_REQUEST​​​​ALWAYS_STRIP​

  • ​NEVER_STRIP​​:即使原始请求路径不包含版本,也不会剥离版本。
  • ​AS_IN_REQUEST​​仅当原始请求路径不包含版本时,才会去除版本。
  • ​ALWAYS_STRIP​​版本始终被剥离,即使原始请求路径包含版本也是如此。

参数(如果提供)用于替换响应标头的一部分。 如果未提供,则使用请求标头的值。​​hostValue​​​​host:port​​​​Location​​​​Host​

参数必须是有效的正则表达式,协议名称与之匹配。 如果不匹配,筛选器将不执行任何操作。 默认值为。​​protocolsRegex​​​​String​​​​http|https|ftp|ftps​

6.18.重写响应标头网关过滤器工厂

工厂采取,和参数。 它使用 Java 正则表达式,以灵活的方式重写响应标头值。 以下示例配置:​​RewriteResponseHeader​​​​GatewayFilter​​​​name​​​​regexp​​​​replacement​​​​RewriteResponseHeader​​​​GatewayFilter​

例 43.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: https://example.org
filters:
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***

对于标头值 ,它设置为在发出下游请求之后。 您必须使用表示因为 YAML 规范。​​/42?user=ford&password=omg!what&flag=true​​​​/42?user=ford&password=***&flag=true​​​​$​​​​$​

6.19.保存会话网关过滤器工厂

工厂在将呼叫转发到下游之前强制操作。 当将 Spring 会话之类的东西与惰性数据存储一起使用时,这特别有用,您需要确保在进行转发调用之前已保存会话状态。 以下示例配置:​​SaveSession​​​​GatewayFilter​​​​WebSession::save​​​​SaveSession​​​​GatewayFilter​

例 44.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: save_session
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession

如果您将 Spring安全性与 Spring会话集成,并希望确保安全详细信息已转发到远程进程,则这一点至关重要。

6.20.安全标头网关过滤器工厂

Thefactory 根据此博客文章中提出的建议向响应添加了许多标头。​​SecureHeaders​​​​GatewayFilter​

添加了以下标头(以其默认值显示):

  • ​X-Xss-Protection:1 (mode=block​​)
  • ​Strict-Transport-Security (max-age=631138519​​)
  • ​X-Frame-Options (DENY)​
  • ​X-Content-Type-Options (nosniff)​
  • ​Referrer-Policy (no-referrer)​
  • ​Content-Security-Policy (default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline)'​
  • ​X-Download-Options (noopen)​
  • ​X-Permitted-Cross-Domain-Policies (none)​

若要更改默认值,请在命名空间中设置相应的属性。 以下属性可用:​​spring.cloud.gateway.filter.secure-headers​

  • ​xss-protection-header​
  • ​strict-transport-security​
  • ​x-frame-options​
  • ​x-content-type-options​
  • ​referrer-policy​
  • ​content-security-policy​
  • ​x-download-options​
  • ​x-permitted-cross-domain-policies​

要禁用默认值,请使用逗号分隔值设置属性。 以下示例演示如何执行此操作:​​spring.cloud.gateway.filter.secure-headers.disable​

spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security

需要使用安全标头的小写全名来禁用它。

6.21.设置路径网关过滤器工厂

工厂采用路径参数。 它提供了一种通过允许路径的模板化段来操作请求路径的简单方法。 这使用 Spring Framework 中的 URI 模板。 允许多个匹配段。 以下示例配置:​​SetPath​​​​GatewayFilter​​​​template​​​​SetPath​​​​GatewayFilter​

例 45.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}

对于请求路径,这会在发出下游请求之前将路径设置为。​​/red/blue​​​​/blue​

6.22.设置请求头网关过滤器工厂

工厂采取沙子参数。 以下清单配置:​​SetRequestHeader​​​​GatewayFilter​​​​name​​​​value​​​​SetRequestHeader​​​​GatewayFilter​

例 46.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
filters:
- SetRequestHeader=X-Request-Red, Blue

这会用给定名称替换(而不是添加)所有标头。 因此,如果下游服务器响应 a,则此内容将替换为下游服务将接收的内容。​​GatewayFilter​​​​X-Request-Red:1234​​​​X-Request-Red:Blue​

​SetRequestHeader​​知道用于匹配路径或主机的 URI 变量。 URI 变量可以在值中使用,并在运行时展开。 以下示例配置使用变量的 an:​​SetRequestHeader​​​​GatewayFilter​

例 47.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetRequestHeader=foo, bar-{segment}

6.23.设置响应头网关过滤器工厂

工厂采取沙子参数。 以下清单配置:​​SetResponseHeader​​​​GatewayFilter​​​​name​​​​value​​​​SetResponseHeader​​​​GatewayFilter​

例 48.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
filters:
- SetResponseHeader=X-Response-Red, Blue

此网关筛选器用给定名称替换(而不是添加)所有标头。 因此,如果下游服务器响应 a,则将其替换为网关客户端将接收的内容。​​X-Response-Red:1234​​​​X-Response-Red:Blue​

​SetResponseHeader​​知道用于匹配路径或主机的 URI 变量。 URI 变量可以在值中使用,并将在运行时展开。 以下示例配置使用变量的 an:​​SetResponseHeader​​​​GatewayFilter​

例 49.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetResponseHeader=foo, bar-{segment}

6.24.设置状态网关过滤器工厂

工厂采用单个参数,。 它必须是有效的弹簧。 它可以是整数值或枚举的字符串表示形式:。 以下清单配置:​​SetStatus​​​​GatewayFilter​​​​status​​​​HttpStatus​​​​404​​​​NOT_FOUND​​​​SetStatus​​​​GatewayFilter​

例 50.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: setstatusstring_route
uri: https://example.org
filters:
- SetStatus=UNAUTHORIZED
- id: setstatusint_route
uri: https://example.org
filters:
- SetStatus=401

在任一情况下,响应的 HTTP 状态都设置为 401。

您可以将 the配置为在响应的标头中从代理请求返回原始 HTTP 状态代码。 如果配置了以下属性,则会将标头添加到响应中:​​SetStatus​​​​GatewayFilter​

例 51.应用程序.yml

spring:
cloud:
gateway:
set-status:
original-status-header-name: original-http-status

6.25.条形前缀网关过滤器工厂

工厂采用一个参数,。 该参数指示路径中要在将请求发送到下游之前从请求中删除的部分数。 以下清单配置:​​StripPrefix​​​​GatewayFilter​​​​parts​​​​parts​​​​StripPrefix​​​​GatewayFilter​

例 52.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2

当通过网关发出请求时,发出的请求看起来像。​​/name/blue/red​​​​nameservice​​​​nameservice/red​

6.26. 重试网关过滤器工厂

工厂支持以下参数:​​Retry​​​​GatewayFilter​

  • ​retries​​:应尝试的重试次数。
  • ​statuses​​:应重试的 HTTP 状态代码,由 using 表示。org.springframework.http.HttpStatus
  • ​methods​​:应重试的 HTTP 方法,由 using 表示。org.springframework.http.HttpMethod
  • ​series​​:要重试的一系列状态代码,由使用表示。org.springframework.http.HttpStatus.Series
  • ​exceptions​​:应重试的引发异常的列表。
  • ​backoff​​:为重试配置的指数退避。 重试是在回退间隔之后执行的,其中是迭代。 配置了 IFIS,应用的最大退避限制为。 如果为 true,退避是通过以下方式计算的。firstBackoff * (factor ^ n)nmaxBackoffmaxBackoffbasedOnPreviousValueprevBackoff * factor

如果启用,则为 filter 配置以下默认值:​​Retry​

  • ​retries​​:三次
  • ​series​​: 5XX系列
  • ​methods​​:获取方法
  • ​exceptions​​:和IOExceptionTimeoutException
  • ​backoff​​:禁用

以下清单配置重试:​​GatewayFilter​

例 53.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: retry_test
uri: http://localhost:8080/flakey
predicates:
- Host=*.retry.com
filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY
methods: GET,POST
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false

使用带有前缀 URL 的重试筛选器时,应仔细编写目标终结点,以便在发生错误时,它不会执行任何可能导致将响应发送到客户端并提交的操作。 例如,如果目标终结点是带批注的控制器,则目标控制器方法不应返回错误状态代码。 相反,它应该抛出 anor 信号错误(例如,通过返回值),重试筛选器可以配置为通过重试来处理该错误。​​forward:​​​​ResponseEntity​​​​Exception​​​​Mono.error(ex)​

将重试筛选器与任何带有正文的 HTTP 方法一起使用时,正文将被缓存,网关将受到内存约束。正文缓存在由 定义的请求属性中。对象的类型为 a。​​ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR​​​​org.springframework.core.io.buffer.DataBuffer​

可以使用单和添加简化的“快捷方式”表示法。​​status​​​​method​

以下两个示例是等效的:

例 54.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: retry_route
uri: https://example.org
filters:
- name: Retry
args:
retries: 3
statuses: INTERNAL_SERVER_ERROR
methods: GET
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false

- id: retryshortcut_route
uri: https://example.org
filters:
- Retry=3,INTERNAL_SERVER_ERROR,GET,10ms,50ms,2,false

6.27.请求大小网关过滤器工厂

当请求大小大于允许的限制时,工厂可以限制请求到达下游服务。 筛选器采用参数。 Theis atype,因此值可以定义为数字后跟可选后缀,例如“KB”或“MB”。字节的默认值为“B”。 它是以字节为单位定义的请求的允许大小限制。 以下清单配置:​​RequestSize​​​​GatewayFilter​​​​maxSize​​​​maxSize​​​​DataSize​​​​DataUnit​​​​RequestSize​​​​GatewayFilter​

例 55.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: http://localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000

当请求因大小而被拒绝时,工厂将响应状态设置为带有附加标头。以下示例显示了这样的一个:​​RequestSize​​​​GatewayFilter​​​​413 Payload Too Large​​​​errorMessage​​​​errorMessage​

errorMessage : Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB

如果未在路由定义中作为筛选器参数提供,则默认请求大小设置为 5 MB。

6.28.设置请求主机头网关过滤器工厂

在某些情况下,可能需要覆盖主机标头。在这种情况下,工厂可以将现有的主机标头替换为指定的 vaue。 筛选器采用参数。 以下清单配置:​​SetRequestHostHeader​​​​GatewayFilter​​​​host​​​​SetRequestHostHeader​​​​GatewayFilter​

例 56.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: set_request_host_header_route
uri: http://localhost:8080/headers
predicates:
- Path=/headers
filters:
- name: SetRequestHostHeader
args:
host: example.org

工厂将主机标头的值替换为。​​SetRequestHostHeader​​​​GatewayFilter​​​​example.org​

6.29. 修改请求正文网关过滤器工厂

您可以使用筛选器筛选器在网关向下游发送请求正文之前对其进行修改。​​ModifyRequestBody​

只能使用 Java DSL 配置此筛选器。

以下清单显示了如何修改请求正文:​​GatewayFilter​

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
(exchange, s) -> return Mono.just(new Hello(s.toUpperCase())))).uri(uri))
.build();
}

static class Hello {
String message;

public Hello() { }

public Hello(String message) {
this.message = message;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}
}

如果请求没有正文,则 将被传递。应返回以在请求中分配缺少的正文。​​RewriteFilter​​​​null​​​​Mono.empty()​

​6.30. 修改响应正文网关过滤器工厂​

您可以使用筛选器在将响应正文发送回客户端之前对其进行修改。​​ModifyResponseBody​

只能使用 Java DSL 配置此筛选器。

以下清单显示了如何修改响应正文:​​GatewayFilter​

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyResponseBody(String.class, String.class,
(exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri))
.build();
}

如果响应没有正文,则 将被传递。应返回以在响应中分配缺少的正文。​​RewriteFilter​​​​null​​​​Mono.empty()​

6.31. 令牌中继网关过滤器工厂

令牌中继是 OAuth2 使用者充当客户端和 将传入令牌转发到传出资源请求。这 使用者可以是纯客户端(如 SSO 应用程序)或资源 服务器。

Spring Cloud Gateway可以将OAuth2访问令牌转发到下游的服务 它是代理。要将此功能添加到网关,您需要添加如下内容:​​TokenRelayGatewayFilterFactory​

应用.java

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("resource", r -> r.path("/resource")
.filters(f -> f.tokenRelay())
.uri("http://localhost:9000"))
.build();
}

或者这个

application.yaml

spring:
cloud:
gateway:
routes:
- id: resource
uri: http://localhost:9000
predicates:
- Path=/resource
filters:
- TokenRelay=

它将(除了登录用户并获取令牌) 将身份验证令牌下游传递到服务(在本例中)。​​/resource​

要为 Spring Cloud 网关启用此功能,请添加以下依赖项

  • ​org.springframework.boot:spring-boot-starter-oauth2-client​

它是如何工作的?这 {githubmaster}/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java[filter] 从当前经过身份验证的用户中提取访问令牌, 并将其放在下游请求的请求标头中。

有关完整的工作示例,请参阅此项目。

只有当设置了适当的属性时,才会创建 Abean,这将触发 abean 的创建。​​TokenRelayGatewayFilterFactory​​​​spring.security.oauth2.client.*​​​​ReactiveClientRegistrationRepository​

默认实现使用 byuse 使用内存中数据存储。如果需要更强大的解决方案,则需要提供自己的实现。​​ReactiveOAuth2AuthorizedClientService​​​​TokenRelayGatewayFilterFactory​​​​ReactiveOAuth2AuthorizedClientService​

6.32.缓存请求正文网关过滤器工厂

有一定情况需要阅读正文。由于请求正文流只能读取一次,因此我们需要缓存请求正文。 您可以使用过滤器在请求正文发送到下游之前缓存请求正文,并从交换属性获取正文。​​CacheRequestBody​

以下清单显示了如何缓存请求正文:​​GatewayFilter​

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("cache_request_body_route", r -> r.path("/downstream/**")
.filters(f -> f.prefixPath("/httpbin")
.cacheRequestBody(String.class).uri(uri))
.build();
}

例 57.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: cache_request_body_route
uri: lb://downstream
predicates:
- Path=/downstream/**
filters:
- name: CacheRequestBody
args:
bodyClass: java.lang.String

​CacheRequestBody​​将提取请求正文并将其转换为正文类(例如,在前面的示例中定义)。然后将其放在 与 定义在的键。​​java.lang.String​​​​ServerWebExchange.getAttributes()​​​​ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR​

此过滤器仅适用于 http 请求(包括 https)。

6.33.JsonToGrpc网关过滤器工厂

JSONToGRPCFilter GatewayFilter Factory 将 JSON 有效负载转换为 gRPC 请求。

筛选器采用以下参数:

  • ​protoDescriptor​​原型描述符文件。

可以使用指定标志生成此文件:​​protoc​​​​--descriptor_set_out​

protoc --proto_path=src/main/resources/proto/ 
--descriptor_set_out=src/main/resources/proto/hello.pb
src/main/resources/proto/hello.proto
  • ​protoFile​​原型定义文件。
  • ​service​​将处理请求的服务的完全限定名称。
  • ​method​​将处理请求的服务中的方法名称。

​streaming​​不受支持。

应用程序.yml.

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("json-grpc", r -> r.path("/json/hello").filters(f -> {
String protoDescriptor = "file:src/main/proto/hello.pb";
String protoFile = "file:src/main/proto/hello.proto";
String service = "HelloService";
String method = "hello";
return f.jsonToGRPC(protoDescriptor, protoFile, service, method);
}).uri(uri))
spring:
cloud:
gateway:
routes:
- id: json-grpc
uri: https://localhost:6565/testhello
predicates:
- Path=/json/**
filters:
- name: JsonToGrpc
args:
protoDescriptor: file:proto/hello.pb
protoFile: file:proto/hello.proto
service: com.example.grpcserver.hello.HelloService
method: hello

当通过网关发出请求时,将使用中提供的定义转换请求,发送到,并将响应转换回JSON。​​/json/hello​​​​hello.proto​​​​com.example.grpcserver.hello.HelloService/hello​

默认情况下,它将创建默认值。但是,这可以通过创建类型的 bean 来自定义:​​NettyChannel​​​​TrustManagerFactory​​​​TrustManager​​​​GrpcSslConfigurer​

@Configuration
public class GRPCLocalConfiguration {
@Bean
public GRPCSSLContext sslContext() {
TrustManager trustManager = trustAllCerts();
return new GRPCSSLContext(trustManager);
}
}

6.34. 默认过滤器

要添加筛选器并将其应用于所有路由,您可以使用。 此属性采用筛选器列表。 下面的清单定义了一组默认筛选器:​​spring.cloud.gateway.default-filters​

spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin
发表评论

相关文章