目錄
6.1.AddRequestHeader
6.2.AddRequestHeadersIfNotPresent
6.3.AddRequestParameter
6.4.AddResponseHeader
6.5.CircuitBreaker
6.5.1. 熔斷指定的狀態(tài)碼
6.6.CacheRequestBody
6.7.DedupeResponseHeader
6.8.FallbackHeaders
6.9.JsonToGrpc
6.10.LocalResponseCache
6.11.MapRequestHeader
6.12.ModifyRequestBody
6.13.ModifyResponseBody
6.14.PrefixPath
6.15.PreserveHostHeader
6.16.RedirectTo
6.17.RemoveJsonAttributesResponseBody
6.18.RemoveRequestHeader
6.19.RemoveRequestParameter
6.20.RemoveResponseHeader
6.21.RequestHeaderSize
6.22.RequestRateLimiter
6.22.1. RedisRateLimiter
6.23.RewriteLocationResponseHeader
6.24.RewritePath
6.25.RewriteResponseHeader
6.26.SaveSession
6.27.SecureHeaders
6.28.SetPath
6.29.SetRequestHeader
6.30.SetResponseHeader
6.31.SetStatus
6.32.StripPrefix
6.33.Retry
6.34.RequestSize
6.35.SetRequestHostHeader
6.36.TokenRelay
6.37. 默認(rèn) Filter
路由(Route)過濾器(Filter)允許以某種方式修改傳入的 HTTP 請求或傳出的 HTTP 響應(yīng)。路由過濾器的范圍是一個(gè)特定的路由。Spring Cloud Gateway 包括許多內(nèi)置的 GatewayFilter 工廠。
關(guān)于如何使用以下任何過濾器的更詳細(xì)的例子,請看 單元測試。
6.1.AddRequestHeader
AddRequestHeader GatewayFilter 工廠需要一個(gè) name 和 value 參數(shù)。下面的例子配置了一個(gè) AddRequestHeader GatewayFilter。
Example 14. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-red, blue
這個(gè)列表將 X-Request-red:blue header添加到所有匹配請求的下游請求的header信息中。
AddRequestHeader 知道用于匹配路徑或主機(jī)的URI變量。URI變量可以在值中使用,并在運(yùn)行時(shí)被擴(kuò)展。下面的例子配置了一個(gè) AddRequestHeader GatewayFilter,它使用一個(gè)變量。
Example 15. 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.AddRequestHeadersIfNotPresent
AddRequestHeadersIfNotPresent GatewayFilter 工廠接受一個(gè)由冒號(hào)分隔的 name 和 value 鍵值對的集合。下面的例子配置了一個(gè) AddRequestHeadersIfNotPresent GatewayFilter。
Example 16. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_headers_route
uri: https://example.org
filters:
- AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-2:green
這個(gè)列表為所有匹配的請求在下游請求的header信息中添加了兩個(gè)header信息 X-Request-Color-1:blue 和 X-Request-Color-2:green。這類似于 AddRequestHeader 的工作方式,但與 AddRequestHeader 不同的是,它只在header 信息不存在的情況下才會(huì)這樣做。否則,客戶端請求中的原始值將被發(fā)送。
此外,要設(shè)置一個(gè)多值header,可以多次使用header的名稱,如 AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-1:green。
AddRequestHeadersIfNotPresent 也支持URI變量,用于匹配路徑或主機(jī)。URI變量可以在值中使用,并在運(yùn)行時(shí)被擴(kuò)展。下面的例子配置了一個(gè)使用變量的 AddRequestHeadersIfNotPresent GatewayFilter。
Example 17. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- AddRequestHeadersIfNotPresent=X-Request-Red:Blue-{segment}
6.3.AddRequestParameter
AddRequestParameter GatewayFilter Factory需要一個(gè) name 和 value 參數(shù)。下面的例子配置了一個(gè) AddRequestParameter GatewayFilter。
Example 18. application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=red, blue
這將為所有匹配的請求在下游請求的查詢字符串中添加 red=blue。
AddRequestParameter 知道用于匹配路徑或主機(jī)的URI變量。URI變量可以在值中使用,并在運(yùn)行時(shí)被擴(kuò)展。下面的例子配置了一個(gè) AddRequestParameter GatewayFilter,它使用了一個(gè)變量。
Example 19. 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.4.AddResponseHeader
AddResponseHeader GatewayFilter 工廠需要一個(gè) name 和 value 參數(shù)。下面的例子配置了一個(gè) AddResponseHeader GatewayFilter。
Example 20. application.yml
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Red, Blue
這將把 X-Response-Red:Blue header添加到所有匹配請求的下游響應(yīng)的header中。
AddResponseHeader 知道用于匹配路徑或主機(jī)的URI變量。URI變量可以在值中使用,并在運(yùn)行時(shí)被擴(kuò)展。下面的例子配置了一個(gè) AddResponseHeader GatewayFilter,它使用了一個(gè)變量。
Example 21. 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.5.CircuitBreaker
Spring Cloud CircuitBreaker GatewayFilter 工廠使用Spring Cloud CircuitBreaker API 將 Gateway 路由包裹在一個(gè)熔斷器中。Spring Cloud CircuitBreaker 支持多個(gè)可與 Spring Cloud Gateway 一起使用的庫。Spring Cloud 支持 Resilience4J 開箱即用。
要啟用 Spring Cloud CircuitBreaker 過濾器,你需要添加 spring-cloud-starter-circuitbreaker-reactor-resilience4j 依賴。下面的例子配置了一個(gè) Spring Cloud CircuitBreaker GatewayFilter。
Example 22. application.yml
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: https://example.org
filters:
- CircuitBreaker=myCircuitBreaker
要配置熔斷器,請參閱你所使用的底層熔斷器實(shí)現(xiàn)的配置。
- Resilience4J 文檔
Spring Cloud CircuitBreaker 過濾器還可以接受一個(gè)可選的 fallbackUri 參數(shù)。目前,只支持 forward: 模式的URI。如果fallback被調(diào)用,請求將被轉(zhuǎn)發(fā)到URI所匹配的控制器。下面的例子配置了這樣一個(gè)fallback。
Example 23. 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來實(shí)現(xiàn)相同的配置,如下。
Example 24. 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();
}
當(dāng)熔斷器 fallback 被調(diào)用時(shí),這個(gè)例子轉(zhuǎn)發(fā)到 /inCaseofFailureUseThis URI。請注意,這個(gè)例子還演示了(可選)Spring Cloud LoadBalancer 的負(fù)載均衡(由目標(biāo)URI上的 lb 前綴定義)。
CircuitBreaker 還支持 fallbackUri 中的URI變量。這允許更復(fù)雜的路由選項(xiàng),比如使用 PathPattern 表達(dá)式 轉(zhuǎn)發(fā)原始主機(jī)或URL路徑的部分。
在下面的例子中,調(diào)用 consumingServiceEndpoint/users/1 將被重定向到 inCaseOfFailureUseThis/users/1。
Example 25. application.yml
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingServiceEndpoint/{*segments}
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis/{segments}
一般情況下是使用 fallbackUri 來定義網(wǎng)關(guān)應(yīng)用程序中的內(nèi)部controller或handler。然而,你也可以將請求重新路由到外部應(yīng)用程序的controller或handler,如下所示。
Example 26. 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
在這個(gè)例子中,網(wǎng)關(guān)應(yīng)用程序中沒有 fallback 端點(diǎn)或處理程序。然而,在另一個(gè)應(yīng)用程序中有一個(gè),在 localhost:9994 下注冊。
在請求被轉(zhuǎn)發(fā)到 fallback 的情況下,Spring Cloud CircuitBreaker Gateway 過濾器也提供了造成這種情況的 Throwable。它作為 ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR 屬性被添加到 ServerWebExchange 中,在網(wǎng)關(guān)應(yīng)用中處理 fallback 時(shí)可以使用。
對于外部 controller/handler 的情況,可以添加帶有異常細(xì)節(jié)的header。你可以在FallbackHeaders GatewayFilter Factory 部分找到更多關(guān)于這樣做的信息。
6.5.1. 熔斷指定的狀態(tài)碼
在某些情況下,你可能想根據(jù)它所包裹的路由返回的狀態(tài)碼來熔斷。斷路器配置對象需要一個(gè)狀態(tài)碼列表,如果返回這些代碼將導(dǎo)致斷路器熔斷。當(dāng)設(shè)置你想讓斷路器熔斷的狀態(tài)代碼時(shí),你可以使用一個(gè)帶有狀態(tài)碼值的 int 或 HttpStatus 枚舉的字符串表示。
Example 27. 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
statusCodes:
- 500
- "NOT_FOUND"
Example 28. 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").addStatusCode("INTERNAL_SERVER_ERROR"))
.rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
.build();
}
6.6.CacheRequestBody
有些情況下,有必要讀取請求體。由于請求體只能被讀取一次,我們需要緩存請求體。你可以使用 CacheRequestBody 過濾器來緩存請求體,然后再把它發(fā)送到下游,從 exchange 屬性中獲取請求體。
下面顯示了如何緩存請求體 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();
}
Example 29. application.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 提取請求體并將其轉(zhuǎn)換為一個(gè) body 類(比如前面例子中定義的 java.lang.String)。然后,CacheRequestBody 把它放在 ServerWebExchange.getAttributes() 提供的屬性中,其KEY值在 ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR 中定義。
這個(gè)過濾器只對HTTP(包括HTTPS)請求起作用。
6.7.DedupeResponseHeader
DedupeResponseHeader GatewayFilter 工廠接受一個(gè) name 參數(shù)和一個(gè)可選的 strategy 參數(shù)。name 可以包含一個(gè)以空格分隔的header名稱列表。下面的例子配置了一個(gè) DedupeResponseHeader GatewayFilter。
Example 30. 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
在網(wǎng)關(guān)CORS邏輯和下游邏輯都添加了 Access-Control-Allow-Credentials 和 Access-Control-Allow-Origin 響應(yīng)頭的情況下,這將刪除重復(fù)的值。
DedupeResponseHeader 過濾器還接受一個(gè)可選的 strategy 參數(shù)。接受的值是 RETAIN_FIRST(默認(rèn))、RETAIN_LAST 和 RETAIN_UNIQUE。
6.8.FallbackHeaders
通過 FallbackHeaders 工廠,你可以在轉(zhuǎn)發(fā)到外部應(yīng)用程序中的 fallbackUri 的請求的header中添加Spring Cloud CircuitBreaker的執(zhí)行異常細(xì)節(jié),如以下場景。
Example 31. 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
在這個(gè)例子中,在運(yùn)行斷路器時(shí)發(fā)生執(zhí)行異常后,請求被轉(zhuǎn)發(fā)到運(yùn)行在 localhost:9994 的應(yīng)用程序中的 fallback 端點(diǎn)或 handler。帶有異常類型、消息和(如果有)根本原因的異常類型和消息的 header 被 FallbackHeaders 過濾器添加到該請求中。
你可以通過設(shè)置以下參數(shù)的值(顯示為默認(rèn)值)來覆蓋配置中header的名稱。
- executionExceptionTypeHeaderName ("Execution-Exception-Type")
- executionExceptionMessageHeaderName ("Execution-Exception-Message")
- rootCauseExceptionTypeHeaderName ("Root-Cause-Exception-Type")
- rootCauseExceptionMessageHeaderName ("Root-Cause-Exception-Message")
關(guān)于斷路器和網(wǎng)關(guān)的更多信息,請參見 Spring Cloud CircuitBreaker Factory 部分 。
6.9.JsonToGrpc
JSONToGRPCFilter GatewayFilter Factory 將一個(gè)JSON payload 轉(zhuǎn)換為gRPC請求。
該過濾器需要以下參數(shù)。
- protoDescriptor: Proto描述文件。
這個(gè)文件可以用 protoc 生成,并指定 --descriptor_set_out 標(biāo)志。
protoc --proto_path=src/main/resources/proto/ \
--descriptor_set_out=src/main/resources/proto/hello.pb \
src/main/resources/proto/hello.proto
- protoFile: Proto定義文件。
- service: 處理請求的服務(wù)的全名稱。
- method: 處理該請求的服務(wù)中的方法名稱。
支持 streaming。 |
application.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
當(dāng)通過網(wǎng)關(guān)向 /json/hello 發(fā)出請求時(shí),該請求通過使用 hello.proto 中提供的定義進(jìn)行轉(zhuǎn)換,發(fā)送到 com.example.grpcserver.hello.HelloService/hello,返回的響應(yīng)被轉(zhuǎn)換為JSON。
默認(rèn)情況下,它通過使用默認(rèn)的 TrustManagerFactory 創(chuàng)建一個(gè) NettyChannel。然而,你可以通過創(chuàng)建一個(gè) GrpcSslConfigurer 類型的bean來定制這個(gè) TrustManager。
@Configuration
public class GRPCLocalConfiguration {
@Bean
public GRPCSSLContext sslContext() {
TrustManager trustManager = trustAllCerts();
return new GRPCSSLContext(trustManager);
}
}
6.10.LocalResponseCache
這個(gè)過濾器允許緩存響應(yīng)體和header,遵循以下規(guī)則。
- 它只能緩存無請求體的GET請求。
- 它只對以下狀態(tài)代碼之一的響應(yīng)進(jìn)行緩存。HTTP 200(OK),HTTP 206(部分內(nèi)容),或HTTP 301(永久移動(dòng))。
- 如果 Cache-Control header不允許,響應(yīng)數(shù)據(jù)就不會(huì)被緩存(請求中存在 no-store 或響應(yīng)中存在 no-store 或 private)。
- 如果響應(yīng)已經(jīng)被緩存,并且在 Cache-Control 頭中用 no-cache 值執(zhí)行一個(gè)新的請求,它將返回一個(gè)304(未修改)的無body的響應(yīng)。
這個(gè)過濾器(配置每個(gè)路由的本地響應(yīng)緩存)只有在啟用了本地響應(yīng)全局緩存的情況下才可用。
它接受第一個(gè)參數(shù),用于覆蓋緩存條目過期的時(shí)間(用 s 表示秒,用 m 表示分鐘,用 h 表示小時(shí)),第二個(gè)參數(shù)用于設(shè)置該路由驅(qū)逐條目的最大緩存大小(KB、MB或GB)。
下面的列表顯示了如何添加本地響應(yīng)緩存 GatewayFilter。
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
.filters(f -> f.prefixPath("/httpbin")
.localResponseCache(Duration.ofMinutes(30), "500MB")
).uri(uri))
.build();
}
或者,這樣:
application.yaml
spring:
cloud:
gateway:
routes:
- id: resource
uri: http://localhost:9000
predicates:
- Path=/resource
filters:
- LocalResponseCache=30m,500MB
這個(gè)過濾器還自動(dòng)計(jì)算 HTTP Cache-Control header中的 max-age 值。只有在原始響應(yīng)中存在 max-age 的情況下,才會(huì)用 timeToLive 配置參數(shù)中設(shè)置的秒數(shù)重寫該值。在連續(xù)的調(diào)用中,這個(gè)值會(huì)以響應(yīng)過期前的剩余秒數(shù)重新計(jì)算。 |
6.11.MapRequestHeader
MapRequestHeader GatewayFilter 工廠接受 fromHeader 和 toHeader 參數(shù)。它創(chuàng)建一個(gè)新的命名header(toHeader),并從傳入的http請求的現(xiàn)有命名頭(fromHeader)中提取值。如果輸入的header不存在,過濾器沒有任何影響。如果新的命名header信息已經(jīng)存在,它的值就會(huì)被增加新的值。下面的例子配置了一個(gè) MapRequestHeader。
Example 32. application.yml
spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Blue, X-Request-Red
這將在下游請求中添加 X-Request-Red:<values> 頭,并從傳入的HTTP請求的 Blue 頭中更新數(shù)值。
6.12.ModifyRequestBody
你可以使用 ModifyRequestBody 過濾器,在網(wǎng)關(guān)向下游發(fā)送請求體之前對其進(jìn)行修改。
這個(gè)過濾器只能通過使用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。應(yīng)該返回 Mono.empty() 來指定請求中缺少的主體。 |
6.13.ModifyResponseBody
你可以使用 ModifyResponseBody 過濾器來修改響應(yīng)體,然后再把它送回給客戶端。
這個(gè)過濾器只能通過使用Java DSL來配置。 |
下面顯示了如何使用 GatewayFilter 修改響應(yīng)體 。
@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();
}
如果響應(yīng)沒有正文,RewriteFilter 將被傳遞為 null。應(yīng)該返回 Mono.empty() 來指定響應(yīng)中缺少的主體。 |
6.14.PrefixPath
PrefixPath GatewayFilter 工廠需要一個(gè) prefix 參數(shù)。下面的例子配置了一個(gè) PrefixPath GatewayFilter。
Example 33. application.yml
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
這就把 /mypath 作為所有匹配請求的路徑的前綴。因此,一個(gè)到 /hello 的請求會(huì)被發(fā)送到 /mypath/hello。
6.15.PreserveHostHeader
PreserveHostHeader GatewayFilter 工廠沒有參數(shù)。這個(gè)過濾器設(shè)置一個(gè)請求屬性(request attribute),路由過濾器(routing filter)會(huì)檢查該屬性,以確定是否應(yīng)該發(fā)送原始的主機(jī)頭,而不是由HTTP客戶端確定的主機(jī)頭。下面的例子配置了一個(gè) PreserveHostHeader GatewayFilter。
Example 34. application.yml
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader
6.16.RedirectTo
RedirectTo GatewayFilter 工廠需要兩個(gè)參數(shù),status 和 url。status 參數(shù)應(yīng)該是一個(gè)300系列的重定向 HTTP 狀態(tài)碼,如301。url 參數(shù)應(yīng)該是一個(gè)有效的URL。這就是 Location header 的值。對于相對重定向,你應(yīng)該使用 uri: no://op 作為路由定義的uri。下面的列表配置了一個(gè) RedirectTo GatewayFilter。
Example 35. application.yml
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
這將發(fā)送一個(gè)帶有 Location:https://acme.org header的302狀態(tài)碼的響應(yīng),以執(zhí)行重定向。
6.17.RemoveJsonAttributesResponseBody
RemoveJsonAttributesResponseBody GatewayFilter 工廠接收了一個(gè)要搜索的屬性名稱(attribute name)集合,列表中的最后一個(gè)參數(shù)可以是一個(gè)布爾值,用來刪除根級(jí)的屬性(如果該參數(shù)未定義,那就是默認(rèn)值 false)或遞歸(true)。它提供了一個(gè)方便的方法,通過刪除屬性來應(yīng)用于JSON body內(nèi)容的轉(zhuǎn)換。
下面的例子配置了一個(gè) RemoveJsonAttributesResponseBody GatewayFilter。
Example 36. application.yml
spring:
cloud:
gateway:
routes:
- id: removejsonattributes_route
uri: https://example.org
filters:
- RemoveJsonAttributesResponseBody=id,color
這從根層的JSON body中刪除了屬性 "id" 和 "color"。
下面的例子配置了一個(gè) RemoveJsonAttributesResponseBody GatewayFilter,它使用了可選的最后參數(shù)。
Example 37. application.yml
spring:
cloud:
gateway:
routes:
- id: removejsonattributes_recursively_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- RemoveJsonAttributesResponseBody=id,color,true
這將從任何級(jí)別的JSON body中移除屬性 "id" 和 "color"。
6.18.RemoveRequestHeader
RemoveRequestHeader GatewayFilter 工廠需要一個(gè) name 參數(shù)。它是要被刪除的header的名稱。下面配置了一個(gè) RemoveRequestHeader GatewayFilter。
Example 38. application.yml
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
這在向下游發(fā)送之前刪除了 X-Request-Foo 標(biāo)頭。
6.19.RemoveRequestParameter
RemoveRequestParameter GatewayFilter 工廠需要一個(gè) name 參數(shù)。它是要?jiǎng)h除的查詢參數(shù)的名稱。下面的例子配置了一個(gè) RemoveRequestParameter GatewayFilter。
Example 39. application.yml
spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route
uri: https://example.org
filters:
- RemoveRequestParameter=red
這將在向下游發(fā)送之前刪除 red 參數(shù)。
6.20.RemoveResponseHeader
RemoveResponseHeader GatewayFilter 工廠需要一個(gè) name 參數(shù)。它是要被移除的 header 的名稱。下面的列表配置了一個(gè) RemoveResponseHeader GatewayFilter。
Example 40. application.yml
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: https://example.org
filters:
- RemoveResponseHeader=X-Response-Foo
這將在響應(yīng)返回到網(wǎng)關(guān)客戶端之前從響應(yīng)中刪除 X-Response-Foo 頭。
要?jiǎng)h除任何類型的敏感標(biāo)頭,你應(yīng)該為任何你可能想這樣做的路由配置這個(gè)過濾器。此外,你可以通過使用 spring.cloud.gateway.default-filters 配置一次此過濾器,并將其應(yīng)用于所有路由。
6.21.RequestHeaderSize
RequestHeaderSize GatewayFilter 工廠接受 maxSize 和 errorHeaderName 參數(shù)。maxSize 參數(shù)是請求頭(包括key和value)所允許的最大數(shù)據(jù)大小。errorHeaderName 參數(shù)設(shè)置包含錯(cuò)誤信息的響應(yīng)頭的名稱,默認(rèn)為 "errorMessage"。下面的列表配置了一個(gè) RequestHeaderSize GatewayFilter。
Example 41. application.yml
spring:
cloud:
gateway:
routes:
- id: requestheadersize_route
uri: https://example.org
filters:
- RequestHeaderSize=1000B
如果任何請求頭的大小超過1000字節(jié),這將發(fā)送一個(gè) 431狀態(tài)碼的響應(yīng)。
6.22.RequestRateLimiter
RequestRateLimiter GatewayFilter 工廠使用 RateLimiter 實(shí)現(xiàn)來確定是否允許當(dāng)前請求繼續(xù)進(jìn)行。如果不允許,就會(huì)返回 HTTP 429 - Too Many Requests(默認(rèn))的狀態(tài)。
這個(gè)過濾器需要一個(gè)可選的 keyResolver 參數(shù)和特定于速率限制器的參數(shù)(在本節(jié)后面描述)。
keyResolver 是一個(gè)實(shí)現(xiàn)了 KeyResolver 接口的Bean。在配置中,使用SpEL來引用Bean的名字。#{@myKeyResolver} 是一個(gè)SpEL表達(dá)式,它引用了一個(gè)名為 myKeyResolver 的bean。下面的列表顯示了 KeyResolver 的接口。
Example 42. KeyResolver.java
public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}
KeyResolver 接口讓可插拔的策略導(dǎo)出限制請求的key。在未來的里程碑版本中,會(huì)有一些 KeyResolver 的實(shí)現(xiàn)。
KeyResolver 的默認(rèn)實(shí)現(xiàn)是 PrincipalNameKeyResolver,它從 ServerWebExchange 中檢索 Principal 并調(diào)用 Principal.getName()。
默認(rèn)情況下,如果 KeyResolver 沒有找到一個(gè) key,請求會(huì)被拒絕。你可以通過設(shè)置 spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key(true 或 false)和 spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code 屬性來調(diào)整這種行為。
RequestRateLimiter 不能用 "快捷方式" 來配置。下面的例子是無效的。 Example 43. application.properties |
6.22.1. RedisRateLimiter
Redis的實(shí)現(xiàn)是基于 Stripe 的工作。它需要使用 spring-boot-starter-data-redis-reactive Spring Boot Starter。
使用的算法是 令牌桶算法。
redis-rate-limiter.replenishRate 屬性定義了每秒鐘允許多少個(gè)請求(不算放棄的請求)。這是令牌桶被填充的速度。
redis-rate-limiter.burstCapacity 屬性是一個(gè)用戶在一秒鐘內(nèi)允許的最大請求數(shù)(不算放棄的請求)。這是令牌桶可以容納的令牌數(shù)量。將此值設(shè)置為零會(huì)阻止所有請求。
redis-rate-limiter.requestedTokens 屬性是指一個(gè)請求要花費(fèi)多少令牌。這是為每個(gè)請求從桶中提取的令牌數(shù)量,默認(rèn)為 1。
一個(gè)穩(wěn)定的速率是通過在 replenishRate 和 burstCapacity 中設(shè)置相同的值來實(shí)現(xiàn)的??梢酝ㄟ^設(shè)置高于補(bǔ)給率的 burstCapacity 來允許臨時(shí)的突發(fā)。在這種情況下,速率限制器需要在突發(fā)之間允許一些時(shí)間(根據(jù) replenishRate),因?yàn)檫B續(xù)兩次突發(fā)會(huì)導(dǎo)致請求被放棄(HTTP 429 - Too Many Requests)。下面的列表配置了一個(gè) redis-rate-limiter。
低于 1個(gè)請求/s 的速率限制是通過將 replenishRate 設(shè)置為想要的請求數(shù), requestTokens 設(shè)置為秒數(shù),burstCapacity 設(shè)置為 replenishRate 和 requestTokens 的乘積來完成的。例如,設(shè)置 replenishRate=1,requestedTokens=60,burstCapacity=60,結(jié)果是1個(gè)請求/分鐘的限制。
Example 44. 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中配置了一個(gè) KeyResolver。
Example 45. Config.java
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
這定義了每個(gè)用戶的請求率限制為10。爆發(fā)20次是允許的,但是,在下一秒,只有10個(gè)請求可用。KeyResolver 是一個(gè)簡單的,獲得 user 請求參數(shù)。
不建議在生產(chǎn)中使用這個(gè)方法 |
你也可以把速率限制器定義為一個(gè)實(shí)現(xiàn) RateLimiter 接口的bean。在配置中,你可以用SpEL來引用bean的名字。#{@myRateLimiter} 是一個(gè)SpEL表達(dá)式,它引用了一個(gè)名為 myRateLimiter 的 bean。下面的清單定義了一個(gè)速率限制器,它使用了前面清單中定義的 KeyResolver。
Example 46. application.yml
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}"
key-resolver: "#{@userKeyResolver}"
6.23.RewriteLocationResponseHeader
RewriteLocationResponseHeader GatewayFilter 工廠修改 Location 響應(yīng)頭的值,通常是為了去掉后臺(tái)的特定細(xì)節(jié)。它需要 stripVersionMode、locationHeaderName、hostValue 和 protocolsRegex 參數(shù)。下面的清單配置了一個(gè) RewriteLocationResponseHeader GatewayFilter。
Example 47. application.yml
spring:
cloud:
gateway:
routes:
- id: rewritelocationresponseheader_route
uri: http://example.org
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
例如,對于一個(gè) POST api.example.com/some/object/name 的請求, Location 響應(yīng)頭值 object-service.prod.example.net/v2/some/object/id 被改寫為 api.example.com/some/object/id。
stripVersionMode 參數(shù)有以下可能的值。NEVER_STRIP、AS_IN_REQUEST(默認(rèn))和 ALWAYS_STRIP。
- NEVER_STRIP: 即使最初的請求路徑不包含version,version也不會(huì)被剝離。
- AS_IN_REQUEST: 只有當(dāng)原始請求路徑不包含version時(shí),才會(huì)剝離version。
- ALWAYS_STRIP: version 總是被剝離,即使原始請求路徑包含version 。
hostValue 參數(shù),如果提供的話,將用于替換響應(yīng)的 Location 頭的 host:port 部分。如果沒有提供,則使用 Host 請求頭的值。
protocolsRegex 參數(shù)必須是一個(gè)有效的 regex String,協(xié)議名稱將與之匹配。如果沒有匹配,過濾器不做任何事情。默認(rèn)是 http|https|ftp|ftps。
6.24.RewritePath
RewritePath GatewayFilter 工廠接收一個(gè)路徑 regexp 參數(shù)和一個(gè) replacement 參數(shù)。這是用Java正則表達(dá)式來重寫請求路徑的一種靈活方式。下面的列表配置了一個(gè) RewritePath GatewayFilter。
Example 48. application.yml
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/red/**
filters:
- RewritePath=/red/?(?<segment>.*), /$\{segment}
對于請求路徑為 /red/blue 的情況,在進(jìn)行下游請求之前將路徑設(shè)置為 /blue。注意,由于YAML的規(guī)范,$ 應(yīng)該被替換成 $\。
6.25.RewriteResponseHeader
RewriteResponseHeader GatewayFilter 工廠接受 name、regexp 和 replacement 參數(shù)。它使用Java正則表達(dá)式,以一種靈活的方式重寫響應(yīng)頭的值。下面的例子配置了一個(gè) RewriteResponseHeader GatewayFilter。
Example 49. application.yml
spring:
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: https://example.org
filters:
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
對于一個(gè) /42?user=ford&password=omg!what&flag=true 的header值,在發(fā)出下游請求后,它被設(shè)置為 /42?user=ford&password=***&flag=true。因?yàn)閅AML規(guī)范,你必須用 $\ 來表示 $。
6.26.SaveSession
SaveSession GatewayFilter 工廠在轉(zhuǎn)發(fā)下游調(diào)用之前強(qiáng)制進(jìn)行 WebSession::save 操作。這在使用類似 Spring Session 的懶數(shù)據(jù)存儲(chǔ)時(shí)特別有用,因?yàn)槟阈枰_保在進(jìn)行轉(zhuǎn)發(fā)調(diào)用之前已經(jīng)保存了Session狀態(tài)。下面的例子配置了一個(gè) SaveSession GatewayFilter。
Example 50. application.yml
spring:
cloud:
gateway:
routes:
- id: save_session
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession
如果你將 Spring Security 與 Spring Session 集成,并希望確保安全細(xì)節(jié)(security detail)已被轉(zhuǎn)發(fā)到遠(yuǎn)程進(jìn)程,這一點(diǎn)至關(guān)重要。
6.27.SecureHeaders
根據(jù) 這篇博客的建議,SecureHeaders GatewayFilter 工廠在響應(yīng)中添加了一些頭信息。
以下header信息(顯示為其默認(rèn)值)被添加。
- 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)
要改變默認(rèn)值,請?jiān)?spring.cloud.gateway.filter.secure-headers 命名空間中設(shè)置相應(yīng)的屬性。以下是可用的屬性。
- xss-protection-header
- strict-transport-security
- frame-options
- content-type-options
- referrer-policy
- content-security-policy
- download-options
- permitted-cross-domain-policies
要禁用默認(rèn)值,請用逗號(hào)分隔的值設(shè)置 spring.cloud.gateway.filter.secure-headers.disable 屬性,如下。
spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
需要使用 secure header 的小寫全名來禁用它。?
6.28.SetPath
SetPath GatewayFilter 工廠接受一個(gè)路徑模板參數(shù)。它提供了一種簡單的方法,通過允許模板化的路徑段來操作請求路徑。這使用了 Spring Framework 的URI模板。允許多個(gè)匹配段。下面的例子配置了一個(gè) SetPath GatewayFilter。
Example 51. application.yml
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}
對于請求路徑為 /red/blue 的情況,在進(jìn)行下行請求之前,將路徑設(shè)置為 /blue。
6.29.SetRequestHeader
SetRequestHeader GatewayFilter 工廠接受 name 和 value 參數(shù)。下面的列表配置了一個(gè) SetRequestHeader GatewayFilter。
Example 52. application.yml
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
filters:
- SetRequestHeader=X-Request-Red, Blue
這 GatewayFilter 會(huì)替換(而不是添加)所有給定名稱的 header 信息。 因此,如果下游服務(wù)器以 X-Request-Red:1234 響應(yīng),它將被替換為 X-Request-Red:Blue,這就是下游服務(wù)會(huì)收到的。
SetRequestHeader 知道用于匹配路徑或主機(jī)的URI變量。URI變量可以在值中使用,并在運(yùn)行時(shí)被擴(kuò)展。下面的例子配置了一個(gè) SetRequestHeader GatewayFilter,它使用了一個(gè)變量。
Example 53. application.yml
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetRequestHeader=foo, bar-{segment}
6.30.SetResponseHeader
SetResponseHeader GatewayFilter 工廠接受 name 和 value 參數(shù)。下面的列表配置了一個(gè) SetResponseHeader GatewayFilter。
Example 54. application.yml
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
filters:
- SetResponseHeader=X-Response-Red, Blue
這個(gè) GatewayFilter 會(huì)替換(而不是添加)所有帶有給定名稱的頭信息。 因此,如果下游服務(wù)器以 X-Response-Red:1234 響應(yīng),它將被替換為 X-Response-Red:Blue,這就是網(wǎng)關(guān)客戶端將收到的內(nèi)容。
SetResponseHeader 知道用于匹配路徑或主機(jī)的URI變量。URI變量可以在值中使用,并將在運(yùn)行時(shí)被擴(kuò)展。下面的例子配置了一個(gè) SetResponseHeader GatewayFilter,它使用了一個(gè)變量。
Example 55. application.yml
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetResponseHeader=foo, bar-{segment}
6.31.SetStatus
SetStatus GatewayFilter 工廠只接受一個(gè)參數(shù),即 status。它必須是一個(gè)有效的Spring HttpStatus。它可以是 404 的int值或枚舉的字符串表示: NOT_FOUND。下面的列表配置了一個(gè) SetStatus GatewayFilter。
Example 56. application.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
在這兩種情況下,響應(yīng)的HTTP狀態(tài)被設(shè)置為401。
你可以配置 SetStatus GatewayFilter,使其在響應(yīng)中的頭中返回代理請求的原始HTTP狀態(tài)代碼。如果配置了以下屬性,該頭會(huì)被添加到響應(yīng)中。
Example 57. application.yml
spring:
cloud:
gateway:
set-status:
original-status-header-name: original-http-status
6.32.StripPrefix
StripPrefix GatewayFilter 工廠需要一個(gè)參數(shù),即 parts。parts 參數(shù)表示在向下游發(fā)送請求之前要從路徑中剝離的部分的數(shù)量。下面的列表配置了一個(gè) StripPrefix GatewayFilter。
Example 58. application.yml
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
當(dāng)通過網(wǎng)關(guān)向 /name/blue/red 發(fā)出請求時(shí),向 nameservice 發(fā)出的請求看起來像 nameservice/red。
6.33.Retry
Retry GatewayFilter 工廠支持以下參數(shù)。
- retries: 應(yīng)該嘗試的重試次數(shù)。
- statuses: 應(yīng)該重試的HTTP狀態(tài)代碼,用 org.springframework.http.HttpStatus 表示。
- methods: 應(yīng)該重試的HTTP方法,用 org.springframework.http.HttpMethod 來表示。
- series: 要重試的狀態(tài)代碼系列,用 org.springframework.http.HttpStatus.Series 表示。
- exceptions: 拋出的異常的列表,應(yīng)該重試。
- backoff: 為重試配置的指數(shù)式backoff。重試是在 backoff 間隔 firstBackoff * (factor ^ n) 之后進(jìn)行的,其中 n 是迭代次數(shù)。如果配置了 maxBackoff,應(yīng)用的最大 backoff 時(shí)間被限制在 maxBackoff。如果 basedOnPreviousValue 為 true,則通過使用 prevBackoff * factor 來計(jì)算backoff。
如果啟用,為 Retry filter 配置的默認(rèn)值如下。
- retries: 三次
- series: 5XX系列
- methods: GET 請求
- exceptions: IOException 和 TimeoutException
- backoff: disabled
下面配置了一個(gè) Retry GatewayFilter。
Example 59. 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
當(dāng)使用帶有 forward: 前綴的URL的 retry filter 時(shí),應(yīng)仔細(xì)編寫目標(biāo)端點(diǎn),以便在出現(xiàn)錯(cuò)誤時(shí),它不會(huì)做任何可能導(dǎo)致響應(yīng)被發(fā)送到客戶端并提交的事情。例如,如果目標(biāo)端點(diǎn)是一個(gè) @Controller,目標(biāo)controller方法不應(yīng)該返回帶有錯(cuò)誤狀態(tài)碼的 ResponseEntity。相反,它應(yīng)該拋出一個(gè) Exception 或發(fā)出一個(gè)錯(cuò)誤信號(hào)(例如,通過 Mono.error(ex) 返回值),retry filter 可以被配置為通過重試來處理。 |
當(dāng)對任何帶有body的HTTP方法使用 retry filter 時(shí),body將被緩存,網(wǎng)關(guān)將變得內(nèi)存受限。body被緩存在 ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR 定義的請求屬性(request attribute)中。該對象的類型是 org.springframework.core.io.buffer.DataBuffer。 |
一個(gè)簡化的 "快捷" 方式可以用一個(gè) status 和 method 來添加。
以下兩個(gè)例子是等同的。
Example 60. application.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.34.RequestSize
當(dāng)請求的大小超過允許的限制時(shí),RequestSize GatewayFilter 工廠可以限制請求到達(dá)下游服務(wù)。該過濾器需要一個(gè) maxSize 參數(shù)。maxSize 是一個(gè) DataSize 類型,所以值可以定義為一個(gè)數(shù)字,后面有一個(gè)可選的 DataUnit 后綴,如 'KB' 或’MB'。默認(rèn)是 'B',表示字節(jié)。它是以字節(jié)為單位定義的請求的可允許的大小限制。下面的列表配置了一個(gè) RequestSize GatewayFilter。
Example 61. 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 工廠將響應(yīng)狀態(tài)設(shè)置為 413 Payload Too Large,當(dāng)請求由于大小而被拒絕時(shí),會(huì)有一個(gè)額外的頭 errorMessage。下面的例子顯示了這樣一個(gè) errorMessage。
errorMessage : Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB
如果在路由定義中沒有提供filter參數(shù),默認(rèn)請求大小被設(shè)置為5MB。?
6.35.SetRequestHostHeader
在某些情況下,host 頭可能需要被重寫。在這種情況下,SetRequestHostHeader GatewayFilter 工廠可以將現(xiàn)有的 host header 替換成指定的值。該過濾器需要一個(gè) host 參數(shù)。下面的列表配置了一個(gè) SetRequestHostHeader GatewayFilter。
Example 62. application.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 工廠將 host 頭的值替換為 example.org。
6.36.TokenRelay
Token Relay是指OAuth2消費(fèi)者作為客戶端,將傳入的令牌轉(zhuǎn)發(fā)給傳出的資源請求。消費(fèi)者可以是一個(gè)純粹的客戶端(如SSO應(yīng)用程序)或一個(gè)資源服務(wù)器。
Spring Cloud Gateway 可以將 OAuth2 訪問令牌轉(zhuǎn)發(fā)到它所代理的服務(wù)的下游。為了在網(wǎng)關(guān)中添加這一功能,你需要像這樣添加 TokenRelayGatewayFilterFactory。
App.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=
它將(除了登錄用戶和抓取令牌之外)把認(rèn)證令牌傳遞給下游的服務(wù)(在這里是 /resource)。
要為 Spring Cloud Gateway 啟用這個(gè)功能,需要添加以下依賴
- org.springframework.boot:spring-boot-starter-oauth2-client
它是如何工作的? {githubmaster}/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java[filter]從當(dāng)前認(rèn)證的用戶中提取一個(gè)訪問令牌,并將其放在下游請求的請求頭中。
完整的工作樣本見 該項(xiàng)目。
只有當(dāng)適當(dāng)?shù)?spring.security.oauth2.client.* 屬性被設(shè)置時(shí), TokenRelayGatewayFilterFactory Bean才會(huì)被創(chuàng)建,這將觸發(fā) ReactiveClientRegistrationRepository Bean的創(chuàng)建。
TokenRelayGatewayFilterFactory 使用的 ReactiveOAuth2AuthorizedClientService 的默認(rèn)實(shí)現(xiàn)使用了一個(gè)內(nèi)存數(shù)據(jù)存儲(chǔ)。如果你需要一個(gè)更強(qiáng)大的解決方案,你將需要提供你自己的實(shí)現(xiàn) ReactiveOAuth2AuthorizedClientService。?
6.37. 默認(rèn) Filter
要添加一個(gè)filter并將其應(yīng)用于所有路由,可以使用 spring.cloud.gateway.default-filters。這個(gè)屬性需要一個(gè)filter的列表。下面的列表定義了一組默認(rèn)filter。文章來源:http://www.zghlxwxcb.cn/news/detail-642092.html
Example 63. application.yml文章來源地址http://www.zghlxwxcb.cn/news/detail-642092.html
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin
到了這里,關(guān)于Spring Cloud Gateway系例—GatewayFilter 工廠的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!