The open-source Spring Cloud Gateway project includes a number of built-in filters for use in Gateway routes. Spring Cloud Gateway provides a number of custom filters in addition to those included in the OSS project.
Filters in Spring Cloud Gateway OSS can be used in Spring Cloud Gateway for Kubernetes. Spring Cloud Gateway OSS includes a number of GatewayFilter
factories used to create filters for routes. For a complete list of these factories, see the Spring Cloud Gateway OSS documentation.
Following sections offers information about the custom filters added in VMware Spring Cloud Gateway and how you can use them.
AddRequestHeadersIfNotPresent
: Request headers modification filterThis filter adds certain request headers if those are not present in the original request. It accepts a list of key value pairs.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
service:
name: myapp
routes:
- predicates:
- Path=/foo
filters:
- AddRequestHeadersIfNotPresent=Content-Type:application/json,Connection:keep-alive
In the example, a raw request to /foo
will have the headers Content-Type: application/json
and Connection: keep-alive
included into the original request.
In case the request comes with:
Content-Type
: only Connection: keep-alive
will be added.Connection
: only Content-Type: application/json
will be added.Content-Type
and Connection
: the original request will be left untouched.AllowedRequestCookieCount
: Allowed request cookie count filterThis filter provides a convenient method to set maximum number of allowed cookies on a request. It accepts up to the maximum number of cookies integer value and will respond with a 431 Request Header Fields Too Large error if exceeded.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
service:
name: myapp
routes:
- ssoEnabled: true
predicates:
- Path=/api/**
filters:
- AllowedRequestCookieCount=2
In the example, request will proceed if it has 2 cookies or less.
AllowedRequestHeadersCount
: Allowed request headers count filterThis filter provides a convenient method to set the maximum allowed headers in the request coming from our target service through the gateway. It accepts a integer value for the maximum number of headers and if it is exceeded it will respond with a 431 Request header fields too large.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
service:
name: myapp
routes:
- ssoEnabled: true
predicates:
- Path=/api/**
filters:
- AllowedRequestHeadersCount=4
In the example, request will proceed if it has 4 or fewer headers, including cookies.
AllowedRequestQueryParamsCount
: Allowed request query params count filterThis filter provides a convenient method to set a maximum allowed query parameters of the request coming from target service through the gateway. It accepts a number of maximum query parameters and it's exceeded, it will respond with a 414 URL Too Large HTTP error.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
service:
name: myapp
routes:
- ssoEnabled: true
predicates:
- Path=/api/**
filters:
- AllowedRequestQueryParamsCount=3
In the example, request will proceed if it has 3 query parameters or less.
BasicAuth
: Basic authorization filterThe BasicAuth
filter relays Basic Authorization credentials to a route. It will not authenticate requests. It will not return a HTTP 401 Unauthorized
status line with a WWW-Authenticate
header for unauthenticated requests.
To use it, you must first store the basic auth username and password in a Kubernetes secret, with their respective keys, username
and password
.
This can be done via:
kubectl create secret generic basic-auth-secret --from-literal=username=***** --from-literal=password=*****
The secret must be in the same namespace as the SpringCloudGatewayRouteConfig
.
Next, in your SpringCloudGatewayRouteConfig
, put the name of the secret you created at spec.basicAuth.secret
.
Finally, add the BasicAuth
filter to the route.
An example is shown below:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: test-gateway-routes
spec:
service:
name: myapp
basicAuth:
secret: basic-auth-secret
routes:
- predicates:
- Path=/api/**
filters:
- StripPrefix=0
- BasicAuth
If you have multiple routes, the Basic Auth credentials will only be relayed to the routes that include the BasicAuth
filter.
If the secret cannot be found, the RouteConfig will not be created. A Kubernetes event will be emitted in that namespace, like so:
$ kubectl get event
LAST SEEN TYPE REASON OBJECT MESSAGE
117s Warning RoutesDefinitionException springcloudgatewaymapping/test-gateway-mapping Failed to retrieve routes from route config in mapping test-gateway-mapping: Failed to find secret 'basic-auth-secret' in the 'user-namespace' namespace.
This will also be logged in the scg-operator
pod, which is in the spring-cloud-gateway
namespace by default:
$ kubectl logs deployment.apps/scg-operator
2021-06-16 19:38:01.459 ERROR 1 --- [ingController-2] c.v.t.s.route.RoutesDefinitionResolver : Failed to find secret 'basic-auth-secret' in the 'user-namespace' namespace.
Note: The BasicAuth
filter will not work together with the TokenRelay
filter as both filters use the Authorization
header.
BlockAccess
: Global Filter to block accessThis is a Global Filter that provides the ability to block access by ip/domain or JWT claims that apply to all existing routes and requests. As it works globally, it must be activated and composed using configuration properties.
spring.cloud.gateway.k8s.block.access.enabled
must be set to true
to enable this filterThere are three configuration properties to setup the possible blocks:
By IP/domain:
spring.cloud.gateway.k8s.block.access.domains
: it accepts a list of IPs or domains separated by commas and will block any request coming from the configured values.By JWT claims:
spring.cloud.gateway.k8s.block.access.claimValues
: it accepts a list of claim values separated by commas, it will search for the specified values in the JWT Claims and will block any authenticated request with any of the configured claim values.spring.cloud.gateway.k8s.block.access.claimNames
: is a complementary property to the previous one, it accepts a list of claim names separated by commas and it will search for the specified values in the claimValues
property in the specified claim names in this property. It will block any authenticated request with any of the configured claim values.Example using only claimValues
property:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
name: my-gateway
spec:
env:
- name: spring.cloud.gateway.k8s.block.access.enabled
value: "true"
- name: spring.cloud.gateway.k8s.block.access.domains
value: "192.168.0.1,test.com"
- name: spring.cloud.gateway.k8s.block.access.claimValues
value: "client.write,cc_testuser"
Will block access if the request comes from test.com
or the IP 192.168.0.1
, it also will block access if any of the JWT claims contains client.write
or cc_testuser
values.
Example using claimValues
and claimNames
properties:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
name: my-gateway
spec:
env:
- name: spring.cloud.gateway.k8s.block.access.enabled
value: "true"
- name: spring.cloud.gateway.k8s.block.access.domains
value: "test.com"
- name: spring.cloud.gateway.k8s.block.access.claimNames
value: "sub"
- name: spring.cloud.gateway.k8s.block.access.claimValues
value: "write,cc_testuser"
Will block access if the request comes from test.com
and it also will block access if the JWT claims sub
contains write
or cc_testuser
values.
Note: The JWT Claim Block Access global filter only supports the block on API calls with the authentication header, it doesn't support blocking by cookie session.
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
JwtKey
: Multiple client JWT validation filterThe JwtKey
filter allows validating JSON Web Tokens (JWT) generated by different providers with different signature keys. It is expected that every request has a key id that allows identifying which key validates the token signature.
SpringCloudGateway integrates with Vault on Kubernetes and assumes a Vault Agent Injector has been deployed to the cluster. This filter requires additional Vault integration parameters defined in the custom resource to be enabled in SpringCloudGateway. The required parameters are serviceAccount.name
, extensions.secretsProviders
, and jwtKey.enabled
alongside jwtKey.secretsProviderName
where:
serviceAccount.name
is the name of the ServiceAccount used by the gateway instancesextensions.secretsProviders
is the element from which keys will be obtained
name
is an arbitrary name to be referenced later on jwtKey
configurationvault.roleName
is the Vault role with read access to the secrets (according to Vault policies configured)vault.path
(optional) is the secret's full path in Vault. For example, for keys my-secrets/scg/keys/123...
and my-secrets/scg/keys/456...
, path must be my-secrets/scg/keys
.vault.authPath
(optional) is the authentication path for Vault's Kubernetes auth method. For example, /auth/cluster-1-auth
, /auth/cluster-2-auth
. If not set, secrets are expected to be under jwt-keys-for-vmware-tanzu/{namespace}-{gateway_name}
jwtKey.enabled
is the flag indicating that the Vault integration is enabledjwtKey.secretsProviderName
is the vault secrets provider name defined previouslyapiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
name: mygateway
spec:
serviceAccount:
name: scg-service-account
extensions:
secretsProviders:
- name: vault-jwt-keys
vault:
roleName: scg-role
filters:
jwtKey:
enabled: true
secretsProviderName: vault-jwt-keys
Secrets within Vault must follow this structure:
secret full name
is the path where the secrets are held. Unless path
property is set in the secretProvider
it must be composed of jwt-keys-for-vmware-tanzu/{namespace}-{gateway_name}/{kid}
kid
is the key id to uniquely identify the public key (RSA
) or the private key (HMAC
). This kid should match the value obtained in the key id locationalg
is the algorithm used to encrypt the public key (currently supporting RSA
only) or the private key (HS256
, HS384
, or HS512
)key
is the actual public key, as a PEM format (supporting both CERTIFICATE
and PUBLIC KEY
formats), or private key with at least 32 bytes in lengthRSA:
vault kv put jwt-keys-for-vmware-tanzu/customnamespace-mygateway/client_0 \
kid="client_0" \
alg="RSA" \
key="-----BEGIN CERTIFICATE-----\
MIIBIyEpEBgkqhkiG9w ..."
HMAC:
vault kv put jwt-keys-for-vmware-tanzu/customnamespace-mygateway/client_0 \
kid="client_0" \
alg="HS256" \
key="Key-Must-Be-at-least-32-bytes-in-length!"
Note: If you need to add, remove or just update a key in Vault, you can use any of Vault supported methods (HTTP API, CLI...) Every interaction will update the keys in the gateway after no more than 5 minutes.
When defining a RouteConfiguration, you can add the JwtKey
filter by including it in the list of filters
for the route.
The configuration provided to the JwtKey filter indicates the key id location. This key id location describes whether the key id is found in an HTTP header or in a JWT claim or header value, with the following syntax:
- JwtKey={header:X-JWT-KEYID}
the key id location is expected to be in an HTTP header named X-JWT-KEYID
- JwtKey={claim:kid}
the key id location is expected to be in a JWT claim or header named kid
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: myapp-route-config
spec:
service:
name: myapp
routes:
- predicates:
- Path=/api/**
filters:
- JwtKey={header:X-JWT-KEYID}
Once the gateway is up and running you can see the loaded keys in the info endpoint. Each key is shown with its id and the time when it was last modified.
"jwtkeys": [
{
"id": "client_0"
"lastRefreshTime": "2021-09-07T07:57:01+0000",
}
]
ApiKey
: API key validation filterThe ApiKey
filter allows validating API keys generated by API portal for VMware Tanzu 1.1.0. It is expected that every request has a X-API-Key
header specified that allows the filter to validate against the hashed value stored in Hashicorp Vault.
SpringCloudGateway integrates with Vault on Kubernetes and assumes a Vault Agent Injector has been deployed to the cluster. This filter requires additional Vault integration parameters defined in the custom resource to be enabled in SpringCloudGateway. The required parameters are serviceAccount.name
, extensions.secretsProviders
, and apiKey.enabled
alongside apiKey.secretsProviderName
where:
serviceAccount.name
is the name of the ServiceAccount used by the gateway instancesextensions.secretsProviders
is the element from which keys will be obtained
name
is an arbitrary name to be referenced later on apiKey
configurationvault.roleName
is the Vault role with read access to the secrets (according to Vault policies configured)vault.path
(optional) is the same vault path you configured when setting up API key management in API portal. If not set, the value will be api-portal-for-vmware-tanzu
by defaultapiKey.enabled
is the flag indicating that the API key validation on all requests is enabledapiKey.secretsProviderName
is the vault secrets provider name defined previouslyapiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
name: mygateway
spec:
api:
groupId: my-group-id
serviceAccount:
name: scg-service-account
extensions:
secretsProviders:
- name: vault-api-keys
vault:
roleName: api-key-role
path: my-api-portal
filters:
apiKey:
enabled: true
secretsProviderName: vault-api-keys
For the example configuration above, to ensure access to the vault path, you need to configure your Hashicorp Vault instance:
Create a Vault access policy to API portal path for the Gateway, including your gateway groupId
(see the configuring instances section for more details)
$ vault policy write scg-policy - <<EOF
path "my-api-portal/data/my-group-id" {
capabilities = ["read"]
}
path "my-api-portal/metadata/my-group-id" {
capabilities = ["list"]
}
EOF
The sample command above uses scg-policy
as the name. You may use a different name for the policy, just make sure you use the same policy name in next step.
Create a role that binds a namespaced service account to that policy, following Kubernetes Auth Method:
$ vault write auth/kubernetes/role/api-key-role \
bound_service_account_names=scg-service-account \
bound_service_account_namespaces=scg-namespace \
policies=scg-policy \
ttl=24h
The bound_service_account_namespaces
above needs to be the namespace where you install your Spring Cloud Gateway instance, and the bound_service_account_names
needs to refer to a service account in the same namespace.
After applying the configuration, all routes defined in the SpringCloudGatewayRouteConfig
will require the X-API-Key
header to be accessed.
For example using an HTTP client such as HTTP or cURL:
$ http GET my-gateway.my-example-domain.com/github X-API-Key:{my-api-key}
$ curl -X GET my-gateway.my-example-domain.com/github --header "X-API-key:{my-api-key}"
If you want to double-check that API key management is enabled and that keys have been loaded, you can visit actuator/info
endpoint which should display:
apikey:
enabled: true
loaded: true
RateLimit
: Limiting user requests filterThe RateLimit
filter limits the number of requests allowed per route during a time window.
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.
Note: If you are using an ingress, ensure it is configured to pass the incoming X-Forwarded-For
header upstream to the gateway.
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/
RewriteJsonAttributesResponseBody
: Response body JSON modification filterThis filter provides a convenient method to apply a transformation to JSON content from target service through the gateway using JSON Path notations. It accepts a list of elements (separated by commas) where the first parameter is the selector of the JSON node and the second one is the value to set into that JSON node, those two parameters must be 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:
- RewriteJsonAttributesResponseBody=slides[1].title:Welcome,date:11-11-2022
Given the following JSON in a body content:
{
"date":"01-01-2022 11:00",
"slides":[
{
"title":"Presentation",
"type":"all"
},
{
"title":"Overview",
"type":"image"
}
],
"title":"Sample Title"
}
Applying the example:
date
at root level will be replaced by 11-11-2022
title
at second element of the slides
array will be replaced by Welcome
{
"date":"11-11-2022",
"slides":[
{
"title":"Presentation",
"type":"all"
},
{
"title":"Welcome",
"type":"image"
}
],
"title":"Sample Title"
}
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
StoreIpAddress
: Store IP address filterThis filter provides a convenient method to store the IP address of the request coming from target service through the gateway, it can be useful for tracing purposes. It accepts a parameter name under which to store the IP.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
service:
name: myapp
filters:
- StoreIpAddress=ipAddress
In the example, will store the IP address in the context of the application under ipAddress
attribute. Attributes can be pulled implementing a custom extension:
((exchange, chain) -> {
String attribute = exchange.getAttributeOrDefault("ipAddress", "Attribute not found");
...
return chain.filter(exchange);
});
StoreHeader
Store headers filterThis filter provides a convenient method to populate a header value into the context of the application coming from target service through the gateway, it can be useful for tracing purposes. It accepts a list of header names to search for and a last parameter with the attribute name under which want to store the header value. It's important to highlight that the list of header names must be in order of priority, once it finds one header, it stops looking for the rest and includes it in the context of the application under the last parameter received.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
service:
name: myapp
filters:
- StoreHeader=x-tracing-header,custom-id,x-custom-id,tracingParam
In the example, will search for x-tracing-header
, custom-id
and x-custom-id
and once it finds one, it will store its value on the application context under tracingParam
attribute. Attributes can be pulled implementing a custom extension:
((exchange, chain) -> {
List<String> attributes = exchange.getAttributeOrDefault("tracingParam", Collections.emptyList());
...
return chain.filter(exchange);
});
SsoAutoAuthorize
: SSO auto-authorized credentials filterThis filter must be applied only for development purposes, it accepts a list of roles or scopes (separated by commas) to inject a fake SSO authorization with those authorities associated.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
service:
name: myapp
filters:
- SsoAutoAuthorize=SCOPE_test,ROLE_test
Additional configuration is required to reduce the change that this local development utility is not deployed to production environments:
JAVA_OPTS
property) com.vmware.tanzu.springcloudgateway.dev.mode.enabled
must be set to true
.com.vmware.tanzu.springcloudgateway.sso.auto.authorize.enabled
must be set to true
.apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
name: my-gateway
spec:
env:
- name: com.vmware.tanzu.springcloudgateway.sso.auto.authorize.enabled
value: "true"
java-opts: "-Dcom.vmware.tanzu.springcloudgateway.dev.mode.enabled=true"
Note: If no SSO configuration is present, you will need to create a dummy configuration activating an SSO profile and setting a valid issuer uri, for example the Google Issuer URL (https://accounts.google.com
).
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
name: my-gateway
spec:
env:
- name: spring.profiles.include
value: "sso"
- name: spring.security.oauth2.client.provider.sso.issuer-uri
value: "https://accounts.google.com"
- name: com.vmware.tanzu.springcloudgateway.sso.auto.authorize.enabled
value: "true"
java-opts: "-Dcom.vmware.tanzu.springcloudgateway.dev.mode.enabled=true"
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.