6. GatewayFilter
工厂
Route filters 允许以某种方式修改传入的 HTTP 请求或返回的 HTTP 响应. Route过滤器适用于特定路由. Spring Cloud Gateway包括许多内置的GatewayFilter 工厂.
有关如何使用以下任意过滤器的更多详细示例, 参考示例 unit tests.
6.1. The AddRequestHeader GatewayFilter Factory
AddRequestHeader
GatewayFilter
factory 有一个 name
和value
的键值对参数. 下面是一个 AddRequestHeader
GatewayFilter
的配置示例:
Example 13. application.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 变量可以在运行时当作value值拓展使用. 下面的示例演示了如何在 AddRequestHeader
GatewayFilter
使用变量:
Example 14. application.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. The AddRequestParameter GatewayFilter Factory
AddRequestParameter
GatewayFilter
工厂有name
和 value
键值对参数. 下面是 AddRequestParameter
GatewayFilter
的配置示例:
Example 15. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=red, blue
这会将 red=blue
添加到所有匹配请求的下游请求的查询字符串中.
AddRequestParameter
能够识别匹配的路径或主机的 URI 变量. URI 变量可以在运行时当作value值拓展使用. 下面的示例演示了如何在 AddRequestParameter
GatewayFilter
使用变量:
Example 16. application.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. The AddResponseHeader GatewayFilter Factory
AddResponseHeader
GatewayFilter
工厂有name
和 value
键值对参数. 下面是 AddResponseHeader
GatewayFilter
配置示例:
Example 17. application.yml
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Red, Blue
此配置将 X-Response-Foo:Bar
响应头添加到所有匹配请求的下游响应头中.
AddResponseHeader
能够识别匹配的路径或主机的 URI 变量. URI 变量可以在运行时当作value值拓展使用. 下面的示例演示了如何在 AddResponseHeader
GatewayFilter
使用变量:
Example 18. application.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. The DedupeResponseHeader GatewayFilter Factory
DedupeResponseHeader GatewayFilter 工厂包含一个name
参数和一个 strategy
可选参数. name
c以包含以空格分隔的 header names 列表. 下面是DedupeResponseHeader
GatewayFilter
配置示例:
Example 19. application.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
and Access-Control-Allow-Origin
响应头的重复值.
DedupeResponseHeader
过滤器还接受可选的 strategy
策略参数. 接收的值为RETAIN_FIRST
(default), RETAIN_LAST
, 和RETAIN_UNIQUE
.
6.5. The Hystrix GatewayFilter Factory
Netflix has put Hystrix in maintenance mode. 我们建议你将 Spring Cloud CircuitBreaker Gateway Filter 和 Resilience4J 一起使用, 因为在将来的版本中将不再支持Hystrix.
Hystrix 是 Netflix 的一个库,用来实现 circuit breaker pattern (断路器模式). Hystrix
GatewayFilter
使你可以将断路器引入网关路由, 保护你的应用免受级联故障的影响,并在下游故障发生时,提供fallback 响应.
如果想要在你的项目中启用 Hystrix
GatewayFilter
, 请添加 对Spring Cloud Netflix 的spring-cloud-starter-netflix-hystrix
的依赖.
Hystrix
GatewayFilter
工厂仅需要一个 name
参数, 即HystrixCommand
的名称. 下面是 Hystrix GatewayFilter
配置示例:
Example 20. application.yml
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: https://example.org
filters:
- Hystrix=myCommandName
将使用 myCommandName
作为名称生成 HystrixCommand
对象来进行熔断管理 .
Hystrix 过滤器还可以接受可选的fallbackUri
参数. 当前, 仅仅支持这种转发的 forward:
schemed URIs . 如果fallback被调用, 请求将会被转发到与URI匹配的 controller 中. 下面的示例配置了一个 fallback:
Example 21. application.yml
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingserviceendpoint
filters:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/incaseoffailureusethis
- RewritePath=/consumingserviceendpoint, /backingserviceendpoint
当 Hystrix fallback被调用时,它将转发到 /incaseoffailureusethis
URI . 请注意,该示例还演示了 (可选) Spring Cloud Netflix Ribbon load-balancing (在目标UR前加了 lb
前缀).
该示例主要方案是将 fallbackUri
指向网关内部的 controller 或 handler . 但是, 你也可以将请求重新路由到外部应用的的 controller 或 handler 中, 如下所示:
Example 22. application.yml
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: Hystrix
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
在此示例中, 网关中没有 fallback
endpoint 或 handler. 但是, 在另一个应用中却有一个, 注册地址为localhost:9994
.
即使将请求转发给了 fallback, Hystrix Gateway filter 依旧会提供提供造成该原因的 Throwable
. 它作为 ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR
属性添加到ServerWebExchange
中, 您可以在网关应用程序中处理fallback时使用该属性.
对于外部controller/handler 解决方案,你可以添加带有异常详细信息的headers .更多详情,请参考FallbackHeaders GatewayFilter Factory section.
你可以设置Hystrix 配置(例如超时),无论是全局配置还是逐条路由配置,更多信息,请参考 Hystrix wiki.
若想为上面的例路由设置五秒钟的超时时间,可以使用以下配置:
Example 23. application.yml
hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000
6.6. Spring Cloud CircuitBreaker GatewayFilter Factory
Spring Cloud CircuitBreaker GatewayFilter工厂使用Spring Cloud CircuitBreaker API将网关路由包装在断路器中。 在 Spring Cloud Gateway中, Spring Cloud CircuitBreaker支持两个库Hystrix和Resilience4J。 由于Netflix已将Hystrix置于仅维护模式,因此建议使用Resilience4J。
若要启用 Spring Cloud CircuitBreaker filter, 你需要将spring-cloud-starter-circuitbreaker-reactor-resilience4j
或spring-cloud-starter-netflix-hystrix
导入到你的 classpath 下. 下面是 Spring Cloud CircuitBreaker GatewayFilter
的配置示例:
Example 24. application.yml
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: https://example.org
filters:
- CircuitBreaker=myCircuitBreaker
要配置断路器,请参阅所使用的断路器的实现的配置。
The Spring Cloud CircuitBreaker filter 过滤器还可以接受可选的fallbackUri
参数. 当前, 仅仅支持这种转发的 forward:
schemed URIs . 如果fallback被调用, 请求将会被转发到与URI匹配的 controller 中. 下面的示例配置了一个 fallback:
Example 25. application.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中也可以实现相同的功能:
Example 26. Application.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();
}
该示例演示了当 circuit breaker fallback被调用时,它将转发到 /inCaseofFailureUseThis
URI . 请注意,该示例还演示了 (可选) Spring Cloud Netflix Ribbon load-balancing (在目标UR前加了 lb
前缀).
该示例主要方案是将 fallbackUri
指向网关内部的 controller 或 handler . 但是, 你也可以将请求重新路由到外部应用的的 controller 或 handler 中, 如下所示:
Example 22. application.yml
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: Hystrix
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
在此示例中, 网关中没有 fallback
endpoint 或 handler. 但是, 在另一个应用中却有一个, 注册地址为localhost:9994
.
如果将请求转发给fallback,同样,Spring Cloud CircuitBreaker网关过滤器也会提供引发该请求的Throwable
. 它作为ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR
属性添加到ServerWebExchange
,可在处理网关应用程序中的fallback 时使用。
对于外部controller/handler 的解决方案,可以添加带有异常详细信息的headers .下一章节我们会详细论述.
6.7. The FallbackHeaders
GatewayFilter
Factory
FallbackHeaders
工厂允许你在在转发到外部应用程序中的fallbackUri
的请求头中添加 Hystrix 或 Spring Cloud CircuitBreaker 执行异常详细信息, 如下所示:
Example 28. application.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
在此示例中, 在运行断路器时发生执行异常之后, 该请求将转发到在运行在 localhost:9994
上的应用程序的fallback
endpoint 或handler . FallbackHeaders
filter将具有异常类型, 消息和(如果有) root cause exception 类型和消息添加到请求头中.
你可以通过设置以下参数的值(以其默认值显示)来覆盖配置中headers的名称:
-
executionExceptionTypeHeaderName
("Execution-Exception-Type"
) -
executionExceptionMessageHeaderName
("Execution-Exception-Message"
) -
rootCauseExceptionTypeHeaderName
("Root-Cause-Exception-Type"
) -
rootCauseExceptionMessageHeaderName
("Root-Cause-Exception-Message"
)
6.8. The MapRequestHeader GatewayFilter Factory
The MapRequestHeader
GatewayFilter
工厂有两个参数 fromHeader
和 toHeader
. 它创建一个新的 header (toHeader
), 然后从传入的http请求中解析现有的(fromHeader
) 的值.如果输入请求中的(fromHeader
) 不存在, 则过滤器不起作用. 反之, 新的 header (toHeader
)的值则设置为(fromHeader
) 的值. 下面是 MapRequestHeader
的配置示例:
Example 29. application.yml
Example 29. application.yml
spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Blue, X-Request-Red
这会将 X-Request-Red:
请求头添加到下游请求中,并赋值为传入HTTP请求的Blue
header的值。
6.9. The PrefixPath GatewayFilter Factory
PrefixPath
GatewayFilter
工厂只有一个 prefix
参数. 下面是 PrefixPath
GatewayFilter
的配置示例:
Example 30. application.yml
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
这会将 /mypath
作为所有匹配请求的路径前缀. 所有访问 /hello
的请求都会被发送到/mypath/hello
.
6.10. The PreserveHostHeader GatewayFilter Factory
PreserveHostHeader
GatewayFilter
工厂没有参数. 该filter 设置请求属性,路由过滤器将检查该请求属性,以确定是否应发送原始host header,而不是由HTTP客户端确定的host header。. The following example configures a PreserveHostHeader
GatewayFilter
:
ServerWebExchange
读取PRESERVE_HOST_HEADER_ATTRIBUTE属性,没有则默认false。如果为true,则proxyRequest.header(HttpHeaders.HOST, host),传递原始的host头部。
Example 31. application.yml
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader
6.11. The RequestRateLimiter GatewayFilter Factory
RequestRateLimiter
GatewayFilter
工厂利用 RateLimiter
的实现来决定是否允许当前的请求继续被执行.如果不允许, 则返回状态码HTTP 429 - Too Many Requests
(默认情况下).
该filter 接受一个可选的keyResolver
参数和特定于速率限制器的参数(本节后面将介绍).
keyResolver
是一个 KeyResolver
接口的实现类.在配置中, 使用 SpEL 按名称引用bean. #{@myKeyResolver}
是一个SpEL 表达式,它引用了名为 myKeyResolver
的bean. 下面示例显示了 KeyResolver
接口:
Example 32. KeyResolver.java
Example 32. KeyResolver.java
public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}
KeyResolver
接口使用可插拔的策略用于生成限制请求的key . 在未来的里程碑版本中, 将会增加一些KeyResolver
的实现类.
KeyResolver
的默认实现是 PrincipalNameKeyResolver
, 它从ServerWebExchange
中检索Principal
并调用 Principal.getName()
.
默认情况下, 如果 KeyResolver
找不到 key, 则拒绝请求. 你可以通过设置 spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key
(true
or false
) and spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code
属性来改变它的行为.
RequestRateLimiter
无法使用 "简洁"符号配置. 下面的示例是无效的:Example 33. application.properties
# INVALID SHORTCUT CONFIGURATION spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
6.11.1. The Redis RateLimiter
Redis的实现基于 Stripe 实现的. 它需要引入spring-boot-starter-data-redis-reactive
Spring Boot starter.
它的算法实现是(令牌桶算法) Token Bucket Algorithm.
redis-rate-limiter.replenishRate
属性是你希望用户每秒允许多少个请求,在请求没有任何丢弃的情况下. 这是令牌桶被填充的速率。.
The redis-rate-limiter.burstCapacity
性是允许用户在一秒钟内执行的最大请求数. 这是令牌桶可以容纳的令牌数. 将此值设置为零将阻止所有请求.
The redis-rate-limiter.requestedTokens
属性是一个请求要花费多少个令牌. 这是每个请求从存储桶中获取的令牌数,默认为 1
.
通过将 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`.
Example 34. application.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实现 KeyResolver 的示例:
Example 35. Config.java
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
这定义了每个用户10的请求速率限制。 允许20个突发,但是在下一秒中,只有10个请求可用。KeyResolver
是一个简单的获取user
请求参数的参数(注意,不建议在生产中使用).
你也可以通过实现 RateLimiter
接口来定义一个速率限制器. 在配置中, 可以使用SpEL按名称引用bean. #{@myRateLimiter}
是一个SpEL表达式, 它引用名为 myRateLimiter
的bean. 以下清单定义了一个速率限制器,该限制器使用上一个清单中定义的 KeyResolver
:
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}"
key-resolver: "#{@userKeyResolver}"
6.12. The RedirectTo GatewayFilter Factory
RedirectTo
GatewayFilter
工厂采用两个参数, 即status
和 url
. 参数 status
是300系列重定向的 HTTP 状态码, 例如 301. 参数 url
应该是一个有效 URL. 它会被 添加到此请求返回的消息中的Location
header的值里. 对于相对路径重定向, 你应该使用 uri: no://op
作为路由定义的uri. 下面是RedirectTo
GatewayFilter
配置示例:
Example 37. application.yml
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
这将发送一个带有Location:https://acme.org
header 的302状态码以执行重定向。
6.13. The RemoveRequestHeader GatewayFilter Factory
RemoveRequestHeader
GatewayFilter
工厂接受一个name
的参数. 它是要删除的header的名称. 下面是RemoveRequestHeader
GatewayFilter
:配置示例
Example 38. application.yml
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
这会在将X-Request-Foo
header发送到下游之前将其删除。
6.14. RemoveResponseHeader GatewayFilter Factory
The RemoveResponseHeader
GatewayFilter
工厂接受一个name
的参数. 它是要删除的header的名称. 下面是RemoveResponseHeader
GatewayFilter
配置示例:
Example 39. application.yml
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: https://example.org
filters:
- RemoveResponseHeader=X-Response-Foo
这将从响应中删除 X-Response-Foo
header,然后将其返回到网关客户端。
若要删除所有的敏感header, 你需要为所有的路由配置该filter. 另外, 你可以使用 spring.cloud.gateway.default-filters
只配置一次,并应用到所有的路由上.
6.15. The RemoveRequestParameter GatewayFilter Factory
RemoveRequestParameter
GatewayFilter
工厂接受一个 name
参数. 它是要被删除的query 参数的名称. 下面是RemoveRequestParameter
GatewayFilter
配置示例:
Example 40. application.yml
spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route
uri: https://example.org
filters:
- RemoveRequestParameter=red
网关会在发送给下游之前将名为 red
query parameter删除.
6.16. The RewritePath GatewayFilter Factory
RewritePath
GatewayFilter
工厂接受一个 path regexp
参数和一个 replacement
参数. 采用了 Java regular 表达式提供了一种灵活的方式重写请求路径. 下面是RewritePath
GatewayFilter
的配置示例:
Example 41. application.yml
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- RewritePath=/red(?<segment>/?.*), $\{segment}
对于请求路径 /red/blue
, 在发送到下游之前,应将路径设置为 /blue
. 注意,你需要将 $
替换成 $\
, 因为这是 YAML 规范.
6.17. RewriteLocationResponseHeader GatewayFilter Factory
RewriteLocationResponseHeader
GatewayFilter
工厂会修改 Location
response header 的值, usually to get rid of backend-specific details. 它输入四个参数 stripVersionMode
, locationHeaderName
, hostValue
, 和protocolsRegex
. 下面是RewriteLocationResponseHeader
GatewayFilter
的配置示例:
Example 42. application.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
的 Locationresponse header
的值object-service.prod.example.net/v2/some/object/id
被重写为 api.example.com/some/object/id
.
stripVersionMode
参数有三个可选值: NEVER_STRIP
, AS_IN_REQUEST
(default), and ALWAYS_STRIP
.
-
NEVER_STRIP
: 版本信息不会被剥离,即使原始请求路径不包含版本 . -
AS_IN_REQUEST
仅当原始请求路径不包含任何版本时,才会剥离版本 [default
]. -
ALWAYS_STRIP
即使原始请求路径包含版本,也会剥离版本 .
参数hostValue
, 如果提供, 会替换response Location
header值中的 host:port
部分.如果没有提供, 则会使用 request header的 Host
作为默认值.
参数protocolsRegex
必须是一个有效的正则表达式字符串, 协议名称与之匹配. 如果不匹配, 该过滤器不起作用. 默认值是 http|https|ftp|ftps
.
6.18. The RewriteResponseHeader GatewayFilter Factory
RewriteResponseHeader
GatewayFilter
工厂接受三个参数 name
, regexp
, 和replacement
.它使用Java正则表达式以灵活的方式重写response header value. 下面是RewriteResponseHeader
GatewayFilter
的配置示例:
Example 43. application.yml
spring:
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: https://example.org
filters:
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
如上所示,header 的X-Response-Red
原始值为/42?user=ford&password=omg!what&flag=true
,当向下游发送请求后会被重置为 /42?user=ford&password=***&flag=true
. 你必须使用 $\
来替代 $
, 因为这是YAML 的规范.
6.19. The SaveSession GatewayFilter Factory
The SaveSession
GatewayFilter
工厂会在想下游发出请求之前强制执行WebSession::save
操作. 对于使用例如 Spring Session 这类延迟数据存储的 ,确保你在向下游转发前保存session 状态时特别有用. 下面是SaveSession
GatewayFilter
配置示例:
Example 44. application.yml
spring:
cloud:
gateway:
routes:
- id: save_session
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession
如果你将 Spring Security 和Spring Session 集成使用 ,并确保安全性详细信息转发到远程进程, 那么这一点至关重要 .
6.20. The SecureHeaders GatewayFilter Factory
SecureHeaders
GatewayFilter
工厂会为响应添加一些列的安全headers, 更多信息,请参考 this blog post.
添加了以下headers (显示其默认值) :
-
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. The SetPath GatewayFilter Factory
SetPath
GatewayFilter
factory 接收一个 template
参数. 它提供了一种简单方法通过允许路径的segments来操作请求路径. 这使用了Spring Framework中的URI模板. 允许多个匹配segments . 下面是SetPath
GatewayFilter
配置示例:
Example 45. application.yml
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}
对于 /red/blue
的请求路径, 在发送给下游请求之前会将路径修改为 /blue
.
6.22. The SetRequestHeader GatewayFilter Factory
SetRequestHeader
GatewayFilter
工厂接收 name
和value
两个参数. 下面是SetRequestHeader
GatewayFilter
配置示例:
Example 46. application.yml
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
filters:
- SetRequestHeader=X-Request-Red, Blue
该GatewayFilter
用于给定名称的headers 替换值(而不是添加) . 因此 , 如果请求头为 X-Request-Red:1234
, 则将其替换为X-Request-Red:Blue
, 这是下游服务将收到的内容.
知道用于匹配路径或主机的URI变量。 URI变量可以在值中使用,并在运行时扩展。 以下示例配置使用变量的
SetRequestHeader
能够识别用于匹配路由或主机的URL变量. URI 变量可以在运行时拓展,并赋值给value中的变量. 下面是SetRequestHeader
GatewayFilter
使用变量的配置示例:
Example 47. application.yml
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetRequestHeader=foo, bar-{segment}
6.23. The SetResponseHeader GatewayFilter Factory
SetResponseHeader
GatewayFilter
工厂接收 name
和value
两个参数. 下面是SetResponseHeader
GatewayFilter
配置示例:
Example 48. application.yml
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
filters:
- SetResponseHeader=X-Response-Red, Blue
该GatewayFilter
用于给定名称的headers 替换值(而不是添加) . 因此 , 如果请求头为 X-Request-Red:1234
, 则将其替换为X-Request-Red:Blue
, 这是gateway client 将收到的内容.
SetResponseHeader
能够识别用于匹配路由或主机的URL变量. URI 变量可以在运行时拓展,并赋值给value中的变量. 下面是SetResponseHeader
GatewayFilter
使用变量的配置示例:
Example 49. application.yml
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetResponseHeader=foo, bar-{segment}
6.24. The SetStatus GatewayFilter Factory
SetStatus
GatewayFilter
工厂接收一个参数 status
. 它必须是有效的 Spring HttpStatus
. 它可以是整数值 404
或枚举的字符串表示形式: NOT_FOUND
. 下面是SetStatus
GatewayFilter
配置示例:
Example 50. application.yml
spring:
cloud:
gateway:
routes:
- id: setstatusstring_route
uri: https://example.org
filters:
- SetStatus=BAD_REQUEST
- id: setstatusint_route
uri: https://example.org
filters:
- SetStatus=401
上面例子中,两种路由都会将响应的状态码设置为401.
你可以将 SetStatus
GatewayFilter
设置为响应的header 从代理请求返回原始的HTTP状态代码. 如果配置如下属性,则header将会添加到response中:
Example 51. application.yml
spring:
cloud:
gateway:
set-status:
original-status-header-name: original-http-status
6.25. The StripPrefix GatewayFilter Factory
StripPrefix
GatewayFilter
工厂接收一个参数, 即parts
. 参数 parts
的意思是在想下游发送请求之前,要从请求中剥离路径中的parts数量. 下面是 StripPrefix
GatewayFilter
的配置示例:
Example 52. application.yml
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
当向网关发送 /name/blue/red
请求时, 对nameservice
的请求则是nameservice/red
.
6.26. The Retry GatewayFilter Factory
Retry
GatewayFilter
工厂支持一下参数:
-
retries
: 应尝试的重试次数. -
statuses
: 应该重试的HTTP 状态码, 用org.springframework.http.HttpStatus
枚举值表示. -
methods
: 需要重试的HTTP请求方法 , 用org.springframework.http.HttpMethod
枚举值表示. -
series
: 要重试的状态码系列, 用org.springframework.http.HttpStatus.Series
枚举值表示.. -
exceptions
: 应重试的异常列表. -
backoff
: 重试配置的指数间隔. 重试在firstBackoff * (factor ^ n)
的窗口间隔之后执行, 其中n
是迭代. 如果maxBackoff
设置了值, 则应用的最大窗口间隔限制为maxBackoff
. 如果basedOnPreviousValue
设为 true, 则通过使用prevBackoff * factor
来计算窗口.
如果启用该filter,下面是 Retry
filter的默认值,:
-
retries
: 3次 -
series
: 5XX 系列 -
methods
: GET 方法 -
exceptions
:IOException
和TimeoutException
-
backoff
: 不启用
下面是 Retry GatewayFilter
的配置示例:
Example 53. application.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
当 retry filter 和
forward:
prefixed URL 结合使用的时候, 应仔细配置 target endpoint, 以便在发生错误的时候,它不会执行本应响应到客户端的的操作. 例如,如果 target endpoint 一个带注释的 controller, 目标 controller 方法不应该返回带有 error status codeResponseEntity
. 相反, 它应该抛出Exception
或错误信号 (例如, 通过Mono.error(ex)
返回值), 通过配置retry filter 来进行retrying处理.
当retry filter和任何具有body的HTTP方法一起使用时, body 将会被缓存, gateway应用受限于内存限制. body 缓存在
ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR
定义的请求属性中. 对象的类型是org.springframework.core.io.buffer.DataBuffer
.
6.27. The RequestSize GatewayFilter Factory
当你想要限制request size的时候 RequestSize
GatewayFilter
工厂可以限制request size超过限制大小的的请求发送到下游服务. 该filter 只有一个 maxSize
参数. 参数maxSize is a
类型, 因此可以将值定义为一个数字, f后跟一个可选的 DataUnit
后缀, 例如 'KB' or 'MB'. 默认时是 'B' (即byte). 它是request size的允许size限制,以bytes为单位 . 下面是 RequestSize
GatewayFilter
的配置示例:
Example 54. application.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
工厂设置response status 为413 Payload Too Large
并附加一个名为errorMessage
的header. 下面的示例显示了errorMessage
:
errorMessage` : `Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB
如果未在路由定义中
RequestSize
GatewayFilter
,则默认请求大小将设置为5 MB.
6.28. Modify a Request Body GatewayFilter Factory
你可以使用 ModifyRequestBody
filter 来修改Request body,然后将其发送到下游服务中.
该filter 只能通过 Java DSL来配置 .
下面显示了如何使用 GatewayFilter
来修改Request body:
@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;
}
}
6.29. Modify a Response Body GatewayFilter Factory
你可以使用 ModifyResponseBody
filter 来修改 Response body 当网关返回到客户端之前.
该filter 只能通过 Java DSL来配置 .
下面的示例显示了如何通过GatewayFilter
来修改Response body :
@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();
}
6.30. Default Filters
若想为所有的路由配置filters ,你可以使用spring.cloud.gateway.default-filters
. 此属性采用filters列表.下面示例定义了一组Default filters:
Example 55. application.yml
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin