Spring Cloud Gateway for Kubernetes supports authentication and authorization using single sign-on (SSO) with an OpenID identity provider that supports OpenID Connect Discovery protocol.
In addition to using an SSO authentication workflow, you can also set up filters to support:
You can configure Spring Cloud Gateway for Kubernetes to authenticate requests via Single Sign-On (SSO), using an OpenID identity provider.
To configure a Gateway instance to use SSO:
Create a file called sso-credentials.txt
, including the following properties:
scope=openid,profile,email
client-id={your_client_id}
client-secret={your_client_secret}
issuer-uri={your-issuer-uri}
For the client-id
, client-secret
, and issuer-uri
values, use values from your OpenID identity provider. For the scope
value, use a list of scopes to include in JWT identity tokens. This list should be based on the scopes allowed by your identity provider.
issuer-uri
configuration should follow Spring Security convention, as described in the official Spring Security documentation:
The provider needs to be configured with an issuer-uri which is the URI that the it asserts as its Issuer Identifier. For example, if the issuer-uri provided is "https://example.com", then an OpenID Provider Configuration Request will be made to "https://example.com/.well-known/openid-configuration". The result is expected to be an OpenID Provider Configuration Response.
Note that only authorization servers supporting OpenID Connect Discovery protocol can be used.
If your authorization server requires Proof Key for Code Exchange (PKCE) as additional verification, add pkce-enabled=true
to sso-credentials.txt
.
Configure external authorization server to allow redirects back to the gateway. Please refer to your authorization server's documentation and add https://<gateway-external-url-or-ip-address>/login/oauth2/code/sso
to the list of allowed redirect URIs.
In the Spring Cloud Gateway for Kubernetes namespace, create a Kubernetes secret using the sso-credentials.txt
file created in the previous step:
$ kubectl create secret generic my-sso-credentials --from-env-file=./sso-credentials.txt
Examine the secret using the kubectl describe
command. Verify that the Data
column of the secret contains all of the required properties listed above.
Add the SSO secret in the SpringCloudGateway
definition in the spec.sso.secret
field. In the routes
list of the SpringCloudGatewayRouteConfig
object, add the setting ssoEnabled: true
to each route that must have authenticated access. See the following updated gateway-config.yaml
and route-config.yaml
files:
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
name: my-gateway
spec:
api:
serverUrl: https://my-gateway.my-example-domain.com
title: Animal Rescue APIs
description: Make and track adoption requests for animals that need to be rescued.
version: "1.0"
sso:
secret: my-sso-credentials
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-gateway-routes
spec:
routes:
- uri: https://github.com
ssoEnabled: true
predicates:
- Path=/github/**
filters:
- StripPrefix=1
With ssoEnabled
set to true
, the Gateway instance will use SSO for all API routes that are configured to allow authenticated access only.
Apply the updated Gateway and RouteConfig definition file:
$ kubectl apply -f gateway-config.yaml
$ kubectl apply -f route-config.yaml
To update the SSO credentials for the gateway:
Update the value in secret (e.g. my-sso-credentials
) by deleting the old secret then recreate it again:
$ kubectl delete secret my-sso-credentials
$ kubectl create secret generic my-sso-credentials --from-env-file=./sso-credentials-updated.txt
Alternatively, edit existing secret with new base64 encoded values:
$ echo $NEW_CLIENT_SECRET | base64 | pbcopy
$ kubectl edit secret my-sso-credentials
Rollout restart the gateway statefulset to enforce secret update:
kubectl rollout restart statefulset my-gateway
Refer to the Okta Tutorial for a tutorial on configuring a gateway with Single Sign-On using Okta for the Animal Rescue demo app.
If you are using the Tanzu Application Platform (TAP) and configured your AppSSO instance with a self-signed certificate, you will need to apply the following yaml as a workaround for the gateway to accept the certificate:
Note: This must be configured separately from the SpringCloudGateway spec's client.tls.secretNames
field.
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: tap-ca-cert
stringData:
type: ca-certificates
ca.crt: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
---
apiVersion: servicebinding.io/v1beta1
kind: ServiceBinding
metadata:
name: sso-cert
spec:
name: sso-cert
service:
apiVersion: v1
kind: Secret
name: tap-ca-cert
workload:
apiVersion: apps/v1
kind: StatefulSet
name: {gateway-name}
where:
{gateway-name}
is the name of the gateway.ca.crt
is your certificate in PEM format.This should be applied before the gateway is created, otherwise the pods might be stuck in a crash loop with the outdated spec. If a crash loop occurs occurs, delete the gateway pods so that the new changes are picked up.
SSO features are equally supported in a Standalone instance. But given the configuration is not handled automatically, there are some considerations about the filter setup on top the required configurations:
Configuration requires adding the filter named SsoLogin
to the route's filters list.
As a rule SsoLogin
filter should be placed always the first in the filters list of a route.
If used in conjunction with TokenRelay
filter, the SsoLogin
must be placed before.
spring:
cloud:
gateway:
routes:
- id: token-relay
uri: https://example.org
filters:
- SsoLogin
- TokenRelay
When SSOEnabled
is set to true
on any route, two securityScheme
(See Swagger Authentication docs) are registered as a component in the OpenAPI spec generated:
And, the schemes are bound to any of those routes. Other routes will not be affected and the scheme will not be applied on them.
Spring Cloud Gateway for Kubernetes instances provide a default API endpoint to log out of the current SSO session: GET /scg-logout
.
If the OIDC provider supports RP-Initiated Logout, the /scg-logout
call will also log the user out of the OIDC provider session.
You can redirect the user to another endpoint or url by adding a redirect
query parameter to the logout call. For example, a GET
call to /scg-logout?redirect=/home
will redirect the user to the /home
page.