The open-source Spring Cloud Gateway project includes a number of built-in filters for use in Gateway routes. Spring Cloud Gateway for VMware Tanzu provides a number of custom filters in addition to those included in the OSS project.
For more detailed documentation on how to use the OSS Spring Cloud Gateway predicates, see the Spring Cloud Gateway OSS predicates documentation.
Predicate | Description |
---|---|
After | matches requests made after a certain datetime |
Before | matches requests made before a certain datetime |
Between | matches requests made between two certain datetimes |
Cookie | matches requests with a certain cookie |
Header | matches requests with a certain header |
Host | matches requests with a certain host pattern |
Method | matches requests to HTTP method (GET/POST) |
Path | matches requests with path of certain pattern(s) |
Query | matches requests with certain query parameter (optional with value pattern) |
RemoteAddr | matches requests of a certain remote IP address |
Weight | Split requests between a set of targets in a group |
Following sections offers information about the custom filters added in Spring Cloud Gateway for VMware Tanzu and how you can use them. Spring Cloud Gateway for VMware Tanzu also adds a number of filters for use with the Single Sign-On for VMware Tanzu tile. For information about these filters, see Using Single Sign-On for VMware Tanzu in Route Configuration.
Filter | Description | |
---|---|---|
AddRequestHeader | Adds a header to a request | |
AddRequestParameter | Adds a request parameter to a request query string | |
AddResponseHeader | Adds a header to a matching response | |
CircuitBreaker | Wraps routes in a circuit breaker | |
ClaimHeader | Copies data from a JWT claim into an HTTP Header | |
ClientCertificateHeader | Validate X-Fowarded-Client-Cert header certificate (optional fingerprint) | |
DeDupeResponseHeader | Removes duplicates of certain headers | |
FallbackHeaders | Adds circuit breaker exception to a header | |
MapRequestHeader | Maps a header from another one | |
PrefixPath | Adds a prefix to a matching request path | |
PreserveHostHeader | Preserves original host header when sending a request | |
RateLimit | Determines if a matching request is allowed to proceed base on volume | |
RedirectTo | Redirects a matching request with certain HTTP code to a certain URL | |
RemoveJsonAttributesResponseBody | Removes JSON attributes and its value from a JSON content | |
RemoveRequestHeader | Removes a header from a matching request | |
RemoveResponseHeader | Removes a header from a response | |
RemoveRequestParameter | Removes a query parameter from a matching request | |
RewriteAllResponseHeaders | Removes a query parameter from a matching request | |
RewritePath | Similar to RewriteResponseHeader, but applies transformation to all headers | |
RewriteLocationResponseHeader | Modifies the value of the location response header | |
RewriteResponseHeader | Rewrite the response header value | |
RewriteResponseBody | Rewrite the response body from a matching request | |
Roles | List authorized roles needed to access route | |
Scopes | List scopes needed to access route | |
SecureHeaders | Adds some headers to a response per a security recommendation | |
SetPath | Manipulates a matching request path | |
SetResponseHeader | Replaces a certain response header | |
SetStatus | Sets HTTP status of a response | |
SSO Login | Redirects to authenticate if no valid Authorization token | |
StripPrefix | Strips parts from a path of a matching request (default: 1) | |
Retry | Retries a matching request | |
RequestSize | Constrains a matching request with a certain request size | |
SetRequestHostHeader | Overrides host header value of a matching request | |
TokenRelay | Forwards OAuth2 access token to downstream resources |
CircuitBreaker
: Reroute traffic on error response filterThe CircuitBreaker
filter provides the ability to reroute a request when an API route is responding with an error response code.
When defining a RouteConfiguration, you can add the CircuitBreaker
filter by including it in the list of filters
for the route. For example, you can add a route with a fallback route to forward on error response:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: myapp-route-config
spec:
service:
name: myapp
routes:
- predicates:
- Path=/api/**
filters:
- CircuitBreaker=myCircuitBreaker,forward:/inCaseOfFailureUseThis
You can also add several options for fine tuning:
- CircuitBreaker=myCircuitBreaker,forward:/inCaseOfFailureUseThis,401:NOT_FOUND:500
- CircuitBreaker=myCircuitBreaker,forward:/inCaseOfFailureUseThis,401:NOT_FOUND:500,10,30s
By querying for the circuit breaker metrics, you can monitor the status of the circuit breaker:
actuator/metrics/resilience4j.circuitbreaker.state?tag=state:{circuit-breaker-state}&tag=name:{circuit-breaker-name}
{circuit-breaker-state}
is one of closed, disabled, half_open, forced_open, open, metrics_only
{circuit-breaker-name}
is the name of your circuit breaker, e.g. myCircuitBreaker
The metrics endpoint will return a value of 1
in the $.measurements[].value
JSON path if the circuit breaker is in this state.
For more more information and other metrics, see Resilience4j CircuitBreaker Metrics.
ClaimHeader
: Passing JWT claims header filterThe ClaimHeader
filter allows passing a JWT claim value as an HTTP Header. It works both with and without SSO enabled, with the consideration that when SSO is not enabled the JWT token is expected in Authorization
Header and won't be validated.
This filter is useful in scenarios where the target service does not handle JWT authorization, but still needs some piece of information from the JWT token.
The ClaimHeader
filter configuration requires 2 parameters:
The following configurations shows how to extract the claim Subject and pass in an HTTP Header called X-Claim-Sub
.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: myapp-route-config
spec:
service:
name: myapp
routes:
- predicates:
- Path=/api/**
filters:
- ClaimHeader=sub,X-Claim-Sub
If you need to pass more than one claim, simply apply the filter repeatedly.
filters:
- ClaimHeader=sub,X-Claim-Sub
- ClaimHeader=iss,X-Claim-Iss
- ClaimHeader=iat,X-Claim-Iat
Note: In case the header is already present, the value(s) from the claim will be added to it. That is, previous values sent in the SCG request will be preserved.
ClientCertificateHeader
: Validate client certificate filterThe ClientCertificateHeader
filter validates the client SSL certificate used to make a request to an app through the Gateway. You can also use this filter to validate the client certifcate's fingerprint.
Note: This filter relies on Kubernetes container's ability to recognize a client certificate's Certificate Authority (CA).
When adding a route to a Gateway service instance, you can add the ClientCertificateHeader
filter by including it in the list of filters
for the applicable route.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: myapp-route-config
spec:
service:
name: myapp
routes:
- predicates:
- Path=/api/**
filters:
- ClientCertificateHeader=*.example.com
To validate the client SSL certificate's fingerprint, add the name of the hash used for the fingerprint, and the fingerprint value, after the CN, using the following format:
[CN],[HASH]:[FINGERPRINT]
where:
[CN]
is the Common Name[HASH]
is the hash used for the fingerprint, either sha-1
or sha-256
[FINGERPRINT]
is the fingerprint valueThe following example uses the ClientCertificateHeader
filter to ensure that a client certificate uses a CN of *.example.com
and a SHA-1 fingerprint of aa:bb:00:99
:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: myapp-route-config
spec:
service:
name: myapp
routes:
- predicates:
- Path=/api/**
filters:
- ClientCertificateHeader=*.example.com,sha-1:aa:bb:00:99
The fingerprint value is not case-sensitive, and the colon character :
is not required to separate hexadecimal digits in a fingerprint. The following example works too:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: myapp-route-config
spec:
service:
name: myapp
routes:
- predicates:
- Path=/api/**
filters:
- ClientCertificateHeader=*.example.com,sha-1:AABB0099
FallbackHeaders
: Allows adding CircuitBreaker
exception details in the headers before forwardingThe FallbackHeaders
filter provides the ability to add CircuitBreaker
execution exception details in the headers of a request forwarded to a fallback route in an external application
When defining a RouteConfiguration, you can add the FallbackHeaders
filter by including it in the list of filters
for the fallback route. For example, you can add the fallback route to add X-Exception
:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: myapp-route-config
spec:
service:
name: myapp
routes:
- predicates:
- Path=/api/**
filters:
- CircuitBreaker="myCircuitBreaker,forward:/inCaseOfFailureUseThis"
- uri: http://localhost:9994
predicates:
- Path=/fallback
filters:
- FallbackHeaders
You can optionally configure just the executionExceptionTypeHeaderName by editing the filter above like:
filters:
- FallbackHeaders= My-Execution-Exception-Type
Or change all executionExceptionTypeHeaderName, executionExceptionMessageHeaderName, rootCauseExceptionTypeHeaderName using the following modification
filters:
- FallbackHeaders= My-Execution-Exception-Type, My-Execution-Exception-Message, My-Root-Cause-Exception-Type
RateLimit
: Limiting user requests filterThe RateLimit
filter limits the number of requests allowed per route during a time window.
By default, Session Management and Rate Limiting use Hazelcast as the default cache implementation. If the operator makes Redis available, developers can opt-in to Redis by setting cache
to redis
. When enabled, a Redis service instance automatically be created and bound to the gateway.
When defining a RouteConfiguration, you can add the RateLimit
filter by including it in the list of filters
for the route. The filter accepts 4 options:
s
, m
or h
suffix to specify it in seconds, minutes or hours.For example, you can add a route to limit all users to one request every 10 seconds:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: myapp-route-config
spec:
service:
name: myapp
routes:
- predicates:
- Path=/api/**
filters:
- RateLimit=1,10s
Provided you are within the allowed limits, the response will succeed and report the number of accepted request you can still do in the X-Remaining
HTTP header. When the limit is exceeded, response will fail with 429 Too Many Requests status, and inform the remaining time until a request will be accepted in X-Retry-In
HTTP header (in milliseconds)
If you want to expose a route for different sets of users, each one identified by its own client_id
HTTP header, use:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: myapp-route-config
spec:
service:
name: myapp
routes:
- predicates:
- Path=/api/**
filters:
- RateLimit=1,10s,{header:client_id}
The rate limit 1,10s
will be applied individually for each set of users. When the header (or claim) is not present access will be rejects with a simple 429 Too Many Requests response (without additional headers).
Rate limiting by IP address can accept a multiple IP addresses, seperated by a semi-colon.
When rate limiting by IP address, the filter checks the X-Forwarded-For
header, if present, for the IP. As there can be multiple IPs added to this header, you can optionally set the max trusted index to read from, by setting this as the first value.
The default value of 1
will read the last IP from the header, while a value of 2
will read the second last IP, and so on. The index must be greater than zero.
Here is an example to rate limit by IP address:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: myapp-route-config
spec:
service:
name: myapp
routes:
- predicates:
- Path=/api/**
filters:
- RateLimit=2,10s,{IPs:2;127.0.0.1;192.168.0.1}
In the example above, the max trusted index is set to 2
. If the X-Forwarded-For
header had a value of 4.4.4.4, 8.8.8.8, 127.0.0.1
, the gateway would return 403 forbidden because the second-last IP, 8.8.8.8
, is not in the allowed IPs. However, if the header was set to 4.4.4.4, 127.0.0.1, 8.8.8.8
, the gateway will return successfully.
RemoveJsonAttributesResponseBody
: Response body modification filterThis filter provides a convenient method to apply a transformation to JSON body content from target service through the gateway. It accepts a list of attribute names to search for and an optional last parameter from the list can be a boolean to remove the attributes just at root level (default value if not present at the end of the parameter configuration, false
) or recursively (true
).
Note: Applying the recursive deletion mode on a large JSON data will affect on service latency.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
service:
name: myapp
routes:
- ssoEnabled: true
predicates:
- Path=/api/**
filters:
- RemoveJsonAttributesResponseBody=origin,foo,true
In the example, the attributes origin
and foo
will be deleted from the JSON content body at any level.
RewriteAllResponseHeaders
Response headers modification filterThis filter provides a convenient method to apply a transformation to all headers coming from target service through the gateway. It accepts a regular expression to search for in header values and text to replace the matching expression with.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
service:
name: myapp
routes:
- ssoEnabled: true
predicates:
- Path=/api/**
filters:
- RewriteAllResponseHeaders=\d,0
In the example, any header value containing a number (\d
matches any number from 0 to 9) will be replaced by 0.
RewriteResponseBody
: Response body modification filterThis filter provides a convenient method to apply a transformation to any body content from target service through the gateway, it won't apply any transformation to response headers. It accepts a list of regular expressions (separated by commas) to search for in value and text to replace the matching expression with (separated by colon).
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
service:
name: myapp
routes:
- ssoEnabled: true
predicates:
- Path=/api/**
filters:
- RewriteResponseBody=foo:bar,/path-one/:/path-two/
In the example, in a body content of any type:
foo
will be replaced by bar
/path-one/
will be replaced by /path-two/
Roles
: Role-based access control filterSimilarly to scope-based access control, it's possible to use custom Claim properties to apply role-base access control with the Roles
filter. Furthermore, if you are not using SSO feature, you can still use role-based control provided you apply JwtKey filter.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
service:
name: myapp
routes:
- ssoEnabled: true
predicates:
- Path=/api/**
filters:
- Roles=role_01,role_02
By default, SpringCloudGateway will check the role values under the roles
claim, but you can change it using spec.sso.roles-attribute-name
property in the Gateway. SCG expects the roles claim to be an array (roles = ["user-role-1", "user-role-2"]
), but a single string is also accepted when role only contains one value (roles = "user-role"
).
Additionally, spec.sso.roles-attribute-name
also supports nested JSON values like custom-data.user.roles
.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
name: mygateway
spec:
sso:
roles-attribute-name: my-roles
Scopes
: Scope-based access control filterWhen SSO is enabled, you can add fine-tune access control based on OIDC scopes by adding the Scopes
filter.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
service:
name: myapp
routes:
- ssoEnabled: true
predicates:
- Path=/api/**
filters:
- Scopes=api.read,api.write,user
TokenRelay
: Passing user identity filterA Token Relay is where an OAuth2 or OIDC consumer acts as a Client and forwards the incoming token to outgoing resource requests. In this case, the consumer can be any service accessible from any of the configured routes with ssoEnabled: true
.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
service:
name: myapp
routes:
- ssoEnabled: true
tokenRelay: true
predicates:
- Path=/api/**
When enabling TokenRelay
, Spring Cloud Gateway for Kubernetes will pass the currently-authenticated user's identity token to the app when the user accesses the app's route.
Note: The TokenRelay
filter will not work together with the BasicAuth
filter as both filters use the Authorization
header.