Filters Included In Spring Cloud Gateway OSS

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.

Available Predicates

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

Available Filters

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 filter

The 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:

  • A list of status codes that will trigger the fallback behaviour, this can be expressed in number and text format separated by a colon.
  • The failure rate threshold above which the circuit breaker will be opened (default 50%, expressed as float value).
  • Duration of wait time before closing again (default 60s).
      - CircuitBreaker=myCircuitBreaker,forward:/inCaseOfFailureUseThis,401:NOT_FOUND:500
      - CircuitBreaker=myCircuitBreaker,forward:/inCaseOfFailureUseThis,401:NOT_FOUND:500,10,30s

Circuit breaker status

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}
  • where {circuit-breaker-state} is one of closed, disabled, half_open, forced_open, open, metrics_only
  • where {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 filter

The 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:

  • Claim name: case sensitive name of the claim to pass.
  • Header name: name of the HTTP

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 filter

The 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 value

The 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 forwarding

The 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 filter

The 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:

  • Number of requests accepted during the window.
  • Duration of the window: by default milliseconds, but you can use s, m or h suffix to specify it in seconds, minutes or hours.
  • (Optional) User partition key: it's also possible to apply rate limiting per user, that is, different users can have its own throughput allowed based on an identifier found in the request. Set whether the key is in a JWT claim or HTTP header with '' or '' syntax.
  • (Optional) It is possible to rate limit by IP addresses. Note, this cannot be combined with the rate limiting per user.

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).

Limiting by IP Address

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 filter

This 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 filter

This 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 filter

This 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 filter

Similarly 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 filter

When 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 filter

A 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.


check-circle-line exclamation-circle-line close-line
Scroll to top icon