- Important Configuration Parameters
- Configuration Reference
- Records
- Admin API
- JSON Web Key Set
- Preparations
- Authentication
- Authorization
- Headers
- Logout
- Debugging
- Changelog
OpenID Connect (1.0) plugin allows the integration with a 3rd party identity provider (IdP) in a standardized way. This plugin can be used to implement Kong as a (proxying) OAuth 2.0 resource server (RS) and/or as an OpenID Connect relying party (RP) between the client, and the upstream service.
The plugin supports several types of credentials and grants:
- Signed JWT access tokens (JWS)
- Opaque access tokens
- Refresh tokens
- Authorization code
- Username and password
- Client credentials
- Session cookies
The plugin has been tested with several OpenID Connect providers:
- Auth0 (Kong Integration Guide)
- Amazon AWS Cognito (Kong Integration Guide)
- Connect2id
- Curity
- Dex
- Gluu
- Google (Kong Integration Guide)
- IdentityServer
- Keycloak
- Microsoft Azure Active Directory (Kong Integration Guide)
- Microsoft Active Directory Federation Services
- Microsoft Live Connect
- Okta (Kong Integration Guide)
- OneLogin
- OpenAM
- Paypal
- PingFederate
- Salesforce
- WSO2
- Yahoo!
As long as your provider supports OpenID Connect standards, the plugin should work, even if it is not specifically tested against it. Let Kong know if you want your provider to be tested and added to the list.
Once applied, any user with a valid credential can access the Service.
This plugin can be used for authentication in conjunction with the Application Registration plugin.
Important Configuration Parameters
This plugin contains many configuration parameters that might seem overwhelming at the start. Here is a list of parameters that you should focus on first:
The first parameter you should configure is:
config.issuer
.This parameter tells the plugin where to find discovery information, and it is the only required parameter. You should specify the
realm
oriss
for this parameter if you don’t have a discovery endpoint.Note: This does not have to match the URL of the
iss
claim in the access tokens being validated. To set URLs supported in theiss
claim, useconfig.issuers_allowed
.Next, you should decide what authentication grants you want to use with this plugin, so configure:
config.auth_methods
.That parameter should contain only the grants that you want to use; otherwise, you inadvertently widen the attack surface.
In many cases, you also need to specify
config.client_id
, and if your identity provider requires authentication, such as on a token endpoint, you will need to specify the client authentication credentials too, for exampleconfig.client_secret
.If you are using a public identity provider, such as Google, you should limit the audience with
config.audience_required
to contain only yourconfig.client_id
. You may also need to adjustconfig.audience_claim
in case your identity provider uses a non-standard claim (other thanaud
as specified in JWT standard). This is because, for example Google, shares the public keys with different clients.If you are using Kong in DB-less mode with the declarative configuration, you should set up
config.session_secret
if you are also using the session cookie authentication. Otherwise, each of your Nginx workers across all your nodes will encrypt and sign the cookies with their own secrets.
In summary, start with the following parameters:
config.issuer
config.auth_methods
config.client_id
(and in many cases the client authentication credentials)config.audience_required
(if using a public identity provider)config.session_secret
(if using the Kong in DB-less mode)
Configuration Reference
This plugin is compatible with DB-less mode.
In DB-less mode, you configure Kong Gateway declaratively. Therefore, the Admin API is mostly read-only. The only tasks it can perform are all related to handling the declarative config, including:
- Setting a target’s health status in the load balancer
- Validating configurations against schemas
- Uploading the declarative configuration using the
/config
endpoint
Enable the plugin on a service
Admin API
Kubernetes
Declarative (YAML)
Konnect Cloud
Kong Manager
For example, configure this plugin on a service by making the following request:
curl -X POST http://{HOST}:8001/services/{SERVICE}/plugins \
--data "name=openid-connect" \
--data "config.auth_methods=authorization_code" \
--data "config.auth_methods=session" \
--data "config.hide_credentials=true" \
--data "config.issuer=<discovery-uri>" \
--data "config.client_id=<client-id>" \
--data "config.client_secret=<client-secret>" \
--data "config.session_secret=<session-secret>" \
--data "config.response_mode=form_post"
SERVICE
is the id
or name
of the service that this plugin configuration will target.
First, create a KongPlugin resource:
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: <openid-connect-example>
config:
auth_methods:
- authorization_code
- session
hide_credentials: true
issuer: <discovery-uri>
client_id:
- <client-id>
client_secret:
- <client-secret>
session_secret: <session-secret>
response_mode: form_post
plugin: openid-connect
Next, apply the KongPlugin resource to a Service by annotating the Service as follows:
apiVersion: v1
kind: Service
metadata:
name: {SERVICE}
labels:
app: {SERVICE}
annotations:
konghq.com/plugins: <openid-connect-example>
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: {SERVICE}
selector:
app: {SERVICE}
{SERVICE}
is the id
or name
of the service that this plugin configuration will target.
Note: The KongPlugin resource only needs to be defined once and can be applied to any service, consumer, or route in the namespace. If you want the plugin to be available cluster-wide, create the resource as a KongClusterPlugin
instead of KongPlugin
.
For example, configure this plugin on a service by adding this section to your declarative configuration file:
plugins:
- name: openid-connect
service: {SERVICE}
config:
auth_methods:
- authorization_code
- session
hide_credentials: true
issuer: <discovery-uri>
client_id:
- <client-id>
client_secret:
- <client-secret>
session_secret: <session-secret>
response_mode: form_post
SERVICE
is the id
or name
of the service that this plugin configuration will target.
Configure this plugin on a service:
- In Konnect Cloud, select the service on the ServiceHub page.
- Scroll down to Versions and select the version.
- Scroll down to Plugins and click New Plugin.
- Find and select the OpenID Connect plugin.
Enter the following parameters, updating the default or sample values as needed:
- Config.Hide Credentials:
true
- Config.Issuer:
<discovery-uri>
- Config.Hide Credentials:
- Click Create.
Configure this plugin on a service:
- In Kong Manager, select the workspace.
- From the Dashboard, scroll down to Services and click View for the service row.
- Scroll down to plugins and click Add Plugin.
Find and select the OpenID Connect plugin.
Note: If the plugin is greyed out, then it is not available for your product tier. See Kong Gateway tiers.
If the option is available, select Scoped.
- Add the service name and ID to the Service field if it is not already prefilled.
Enter the following parameters, updating the default or sample values as needed:
- Config.Hide Credentials:
true
- Config.Issuer:
<discovery-uri>
- Config.Hide Credentials:
- Click Create.
Enable the plugin on a route
Admin API
Kubernetes
Declarative (YAML)
Konnect Cloud
Kong Manager
For example, configure this plugin on a route with:
$ curl -X POST http://{HOST}:8001/routes/{ROUTE}/plugins \
--data "name=openid-connect" \
--data "config.auth_methods=authorization_code" \
--data "config.auth_methods=session" \
--data "config.hide_credentials=true" \
--data "config.issuer=<discovery-uri>" \
--data "config.client_id=<client-id>" \
--data "config.client_secret=<client-secret>" \
--data "config.session_secret=<session-secret>" \
--data "config.response_mode=form_post"
ROUTE
is the id
or name
of the route that this plugin configuration will target.
First, create a KongPlugin resource:
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: <openid-connect-example>
config:
auth_methods:
- authorization_code
- session
hide_credentials: true
issuer: <discovery-uri>
client_id:
- <client-id>
client_secret:
- <client-secret>
session_secret: <session-secret>
response_mode: form_post
plugin: openid-connect
Then, apply it to an ingress (Route or Routes) by annotating the ingress as follows:
apiVersion: networking/v1beta1
kind: Ingress
metadata:
name: {ROUTE}
annotations:
kubernetes.io/ingress.class: kong
konghq.com/plugins: <openid-connect-example>
spec:
rules:
- host: examplehostname.com
http:
paths:
- path: /bar
backend:
serviceName: echo
servicePort: 80
ROUTE
is the id
or name
of the route that this plugin configuration will target.
Note: The KongPlugin resource only needs to be defined once and can be applied to any service, consumer, or route in the namespace. If you want the plugin to be available cluster-wide, create the resource as a KongClusterPlugin
instead of KongPlugin
.
For example, configure this plugin on a route by adding this section to your declarative configuration file:
plugins:
- name: openid-connect
route: <route>
config:
auth_methods:
- authorization_code
- session
hide_credentials: true
issuer: <discovery-uri>
client_id:
- <client-id>
client_secret:
- <client-secret>
session_secret: <session-secret>
response_mode: form_post
ROUTE
is the id
or name
of the route that this plugin configuration will target.
Configure this plugin on a route:
- In Konnect Cloud, select the service from the ServiceHub page.
- Scroll down to Versions and select the version.
- Select the route.
- Scroll down to Plugins and click Add Plugin.
- Find and select the OpenID Connect plugin.
Enter the following parameters, updating the default or sample values as needed:
- Config.Hide Credentials:
true
- Config.Issuer:
<discovery-uri>
- Config.Hide Credentials:
- Click Create.
Configure this plugin on a route:
- In Kong Manager, select the workspace.
- From the Dashboard, select Routes in the left navigation.
- Click View for the route row.
- Scroll down to plugins and click Add Plugin.
Find and select the OpenID Connect plugin.
Note: If the plugin is greyed out, then it is not available for your product tier. See Kong Gateway tiers.
If the option is available, select Scoped.
- Add the Route ID if it is not already prefilled.
Enter the following parameters, updating the default or sample values as needed:
- Config.Hide Credentials:
true
- Config.Issuer:
<discovery-uri>
- Config.Hide Credentials:
- Click Create.
Enable the plugin globally
A plugin which is not associated to any service, route, or consumer is considered global, and will be run on every request. Read the Plugin Reference and the Plugin Precedence sections for more information.
Admin API
Kubernetes
Declarative (YAML)
Kong Manager
For example, configure this plugin globally with:
$ curl -X POST http://{HOST}:8001/plugins/ \
--data "name=openid-connect" \
--data "config.auth_methods=authorization_code" \
--data "config.auth_methods=session" \
--data "config.hide_credentials=true" \
--data "config.issuer=<discovery-uri>" \
--data "config.client_id=<client-id>" \
--data "config.client_secret=<client-secret>" \
--data "config.session_secret=<session-secret>" \
--data "config.response_mode=form_post"
Create a KongClusterPlugin resource and label it as global:
apiVersion: configuration.konghq.com/v1
kind: KongClusterPlugin
metadata:
name: <global-openid-connect>
annotations:
kubernetes.io/ingress.class: kong
labels:
global: \"true\"
config:
auth_methods:
- authorization_code
- session
hide_credentials: true
issuer: <discovery-uri>
client_id:
- <client-id>
client_secret:
- <client-secret>
session_secret: <session-secret>
response_mode: form_post
plugin: openid-connect
For example, configure this plugin using the plugins:
entry in the declarative configuration file:
plugins:
- name: openid-connect
config:
auth_methods:
- authorization_code
- session
hide_credentials: true
issuer: <discovery-uri>
client_id:
- <client-id>
client_secret:
- <client-secret>
session_secret: <session-secret>
response_mode: form_post
Configure this plugin globally:
- In Kong Manager, select the workspace.
- From the Dashboard, select Plugins in the left navigation.
- Click New Plugin.
Find and select the OpenID Connect plugin.
Note: If the plugin is greyed out, then it is not available for your product tier. See Kong Gateway tiers.
If the option is available, set the plugin scope to Global.
Enter the following parameters, updating the default/sample values as needed:
- Config.Hide Credentials:
true
- Config.Issuer:
<discovery-uri>
- Config.Hide Credentials:
- Click Create.
Parameters
Here’s a list of all the parameters which can be used in this plugin’s configuration:
Form Parameter | Description |
---|---|
name required Type: string | The name of the plugin, in this case openid-connect . |
service.id Type: string | The ID of the Service the plugin targets. |
route.id Type: string | The ID of the Route the plugin targets. |
enabled required Type: boolean Default value: true | Whether this plugin will be applied. |
Authentication Grants Parameters for enabling only grants/credentials that you want to use. | |
Form Parameter | Description |
config.authmethods optional Type: array of string elements Default value: [“password”, “client_credentials”, “authorization_code”, “bearer”, “introspection”, “userinfo”, “kong_oauth2”, “refresh_token”, “session”] | Types of credentials/grants to enable:
|
Anonymous Access Parameter for allowing anonymous access. This parameter is disabled by default. | |
Form Parameter | Description |
config.anonymous optional Type: uuid | Let unauthenticated requests pass or skip the plugin if another authentication plugin has already authenticated the request by setting the value to anonymous Consumer. |
General Settings Parameters for settings that affect different grants and flows. | |
Form Parameter | Description |
config.preserve_query_args optional Type: boolean Default value: false | With this parameter, you can preserve request query arguments even when doing authorization code flow.
|
config.refresh_tokens optional Type: boolean Default value: true | Specifies whether the plugin should try to refresh (soon to be) expired access tokens if the plugin has a |
config.hide_credentials required Type: boolean Default value: true | Remove the credentials used for authentication from the request.
|
config.search_user_info optional Type: boolean Default value: false | Specify whether to use the user info endpoint to get addition claims for consumer mapping, credential mapping, authenticated groups, and upstream and downstream headers.
|
Discovery Parameters for auto-configuring most of the settings and providing the means for key rotation. | |
Form Parameter | Description |
config.issuer required Type: url | The discovery endpoint (or just the issuer identifier).
|
config.rediscovery_lifetime optional Type: integer Default value: 30 | Specifies how often (in seconds) the plugin completes a re-discovery.
|
Client | |
Form Parameter | Description |
config.client_id optional Type: array of string elements (the plugin supports multiple clients) | The client id(s) that the plugin uses when it calls authenticated endpoints on the identity provider. Other settings that are associated with the client are:
Use the same array index when configuring related settings for the client. This field is referenceable, which means it can be securely stored as a secret in a vault. References must follow a specific format. If keyring database encryption is enabled, this value will be encrypted. |
config.client_arg optional Type: string | The client to use for this request (the selection is made with a request parameter with the same name). For example, setting this value to |
Client Authentication Parameters for configuring how the client should authenticate with the identity provider. | |
Form Parameter | Description |
config.client_auth optional Type: array of string elements (one for each client) Default value: (discovered or “client_secret_basic”) | The authentication method used by the client (plugin) when calling the endpoints:
|
config.client_secret optional Type: array of string elements (one for each client) | The client secret.
This field is referenceable, which means it can be securely stored as a secret in a vault. References must follow a specific format. If keyring database encryption is enabled, this value will be encrypted. |
config.client_jwk optional Type: array of JWK records (one for each client) Default value: (plugin managed) | The JWK used for the |
config.client_alg optional Type: array of string elements (one for each client) Default value: (client_secret_jwt: “HS256”, private_key_jwt: “RS256”) | The algorithm to use for
|
JWT Access Token Authentication Parameters for setting where to search for the bearer token and whether to introspect them. | |
Form Parameter | Description |
config.bearer_token_param_type optional Type: array of string elements Default value: [“header”, “query”, “body”] | Where to search for the bearer token:
|
config.bearer_token_cookie_name optional Type: string | The name of the cookie in which the bearer token is passed. |
config.introspect_jwt_tokens optional Type: boolean Default value: false | Specifies whether to introspect the JWT access tokens (can be used to check for revocations). |
Client Credentials Grant Parameters for where to search for the client credentials. | |
Form Parameter | Description |
config.client_credentials_param_type optional Type: array of string elements Default value: [“header”, “query”, “body”] | Where to search for the client credentials:
|
Password Grant Parameters for where to search for the username and password. | |
Form Parameter | Description |
config.password_param_type optional Type: array of string elements Default value: [“header”, “query”, “body”] | Where to search for the username and password:
|
Refresh Token Grant Parameters for where to search for the refresh token (rarely used as the refresh tokens are in many cases bound to the client). | |
Form Parameter | Description |
config.refresh_token_param_type optional Type: array of string elements Default value: [“header”, “query”, “body”] | Where to search for the refresh token:
|
config.refresh_token_param_name optional Type: string | The name of the parameter used to pass the refresh token. |
ID Token Parameters for where to search for the id token (rarely sent as part of the request). | |
Form Parameter | Description |
config.id_token_param_type optional Type: array of string elements Default value: [“header”, “query”, “body”] | Where to search for the id token:
|
config.id_token_param_name optional Type: string | The name of the parameter used to pass the id token. |
Consumer Mapping Parameters for mapping external identity provider managed identities to Kong managed ones. | |
Form Parameter | Description |
config.admin_claim optional Type: string | The claim used for admin mapping for Kong Manager. Required if mapping IdP claims to Kong Manager admins. |
config.consumer_claim optional Type: array of string elements | The claim used for consumer mapping. |
config.consumer_by optional Type: array of string elements Default value: [“username”, “custom_id”] | Consumer fields used for mapping:
|
config.by_username_ignore_case optional Type: boolean Default value: false | If |
config.consumer_optional optional Type: boolean Default value: false | Do not terminate the request if consumer mapping fails. |
Credential Mapping Parameters for mapping external identity provider managed identities to a Kong credential (virtual in this case). | |
Form Parameter | Description |
config.credential_claim optional Type: array of string elements Default value: [“sub”] | The claim used to derive a virtual credential (for instance, for the rate-limiting plugin), in case the Consumer mapping is not used. |
Issuer Verification | |
Form Parameter | Description |
config.issuers_allowed optional Type: array of string elements Default value: (discovered issuer) | The issuers allowed to be present in the tokens ( |
Authorization | |
Form Parameter | Description |
config.authenticated_groups_claim optional Type: array of string elements | The claim that contains authenticated groups. This setting can be used together with ACL plugin, but it also enables IdP managed groups with other applications and integrations (for example, Kong Manager and Dev Portal). The OpenID Connect plugin itself does not do anything other than set the context value. |
config.scopes_required optional Type: array of string elements Default value: (discovered issuer) | The scopes (
|
config.scopes_claim optional Type: array of string elements Default value: [“scope”] | The claim that contains the scopes. |
config.audience_required optional Type: array of string elements | The audiences (
|
config.audience_claim optional Type: array of string elements Default value: [“aud”] | The claim that contains the audience. |
config.groups_required optional Type: array of string elements | The groups (
|
config.groups_claim optional Type: array of string elements Default value: [“groups”] | The claim that contains the groups. |
config.roles_required optional Type: array of string elements | The roles (
|
config.roles_claim optional Type: array of string elements Default value: [“roles”] | The claim that contains the roles. |
Claims Verification Parameters for verification rules for standard claims. | |
Form Parameter | Description |
config.verify_claims optional Type: boolean Default value: true | Verify tokens for standard claims. |
config.leeway optional Type: integer Default value: 0 | Allow some leeway on the ttl / expiry verification. |
config.domains optional Type: array of string elements | The allowed values for the |
config.max_age optional Type: integer | The maximum age (in seconds) compared to the |
config.jwt_session_claim optional Type: string Default value: “sid” | The claim to match against the JWT session cookie. |
config.jwt_session_cookie optional Type: string | The name of the JWT session cookie. |
Signature Verification | |
Form Parameter | Description |
config.verify_signature optional Type: boolean Default value: true | Verify signature of tokens. |
config.enable_hs_signatures optional Type: boolean Default value: false | Enable shared secret, for example, HS256, signatures (when disabled they will not be accepted). |
config.ignore_signature optional Type: array of string elements | Skip the token signature verification on certain grants:
|
config.extra_jwks_uris optional Type: array of string elements | JWKS URIs whose public keys are trusted (in addition to the keys found with the discovery). |
Authorization Code Flow Verification | |
Form Parameter | Description |
config.verify_nonce optional Type: boolean Default value: true | Verify nonce on authorization code flow. |
Introspection Verification | |
Form Parameter | Description |
config.introspection_check_active optional Type: boolean Default value: true | Check that the introspection response has an |
Configuration Verification | |
Form Parameter | Description |
config.verify_parameters optional Type: boolean Default value: false | Verify plugin configuration against discovery. |
Upstream Headers Parameters for the headers for the upstream service request. | |
Form Parameter | Description |
config.upstream_headers_claims optional Type: array of string elements | The upstream header claims. |
config.upstream_headers_names optional Type: array of string elements | The upstream header names for the claim values. |
config.upstream_access_token_header optional Type: string Default value: authorization:bearer | The upstream access token header. |
config.upstream_access_token_jwk_header optional Type: string | The upstream access token JWK header. |
config.upstream_id_token_header optional Type: string | The upstream id token header. |
config.upstream_id_token_jwk_header optional Type: string | The upstream id token JWK header. |
config.upstream_refresh_token_header optional Type: string | The upstream refresh token header. |
config.upstream_user_info_header optional Type: string | The upstream user info header. |
config.upstream_user_info_jwt_header optional Type: string | The upstream user info JWT header (in case the user info returns a JWT response). |
config.upstream_introspection_header optional Type: string | The upstream introspection header. |
config.upstream_introspection_jwt_header optional Type: string | The upstream introspection header (in case the introspection returns a JWT response). |
config.upstream_session_id_header optional Type: string | The upstream session id header. |
Downstream Headers Parameters for the headers for the downstream response. | |
Form Parameter | Description |
config.downstream_headers_claims optional Type: array of string elements | The downstream header claims. |
config.downstream_headers_names optional Type: array of string elements | The downstream header names for the claim values. |
config.downstream_access_token_header optional Type: string Default value: authorization:bearer | The downstream access token header. |
config.downstream_access_token_jwk_header optional Type: string | The downstream access token JWK header. |
config.downstream_id_token_header optional Type: string | The downstream id token header. |
config.downstream_id_token_jwk_header optional Type: string | The downstream id token JWK header. |
config.downstream_refresh_token_header optional Type: string | The downstream refresh token header. |
config.downstream_user_info_header optional Type: string | The downstream user info header. |
config.downstream_user_info_jwt_header optional Type: string | The downstream user info JWT header (in case the user info returns a JWT response). |
config.downstream_introspection_header optional Type: string | The downstream introspection header. |
config.downstream_introspection_jwt_header optional Type: string | The downstream introspection header (in case the introspection returns a JWT response). |
config.downstream_session_id_header optional Type: string | The downstream session id header. |
Cross-Origin Resource Sharing (CORS) | |
Form Parameter | Description |
config.run_on_preflight optional Type: boolean Default value: true | Specifies whether to run this plugin on pre-flight ( |
Login Parameters for what action the plugin completes after a successful login. | |
Form Parameter | Description |
config.login_methods optional Type: array of string elements Default value: [“authorization_code”] | Enable login functionality with specified grants:
|
config.login_action optional Type: string Default value: “upstream” | What to do after successful login:
|
config.login_tokens optional Type: array of string elements Default value: [“id_token”] | What tokens to include in
|
config.login_redirect_mode optional Type: string Default value: “fragment” | Where to place
|
config.login_redirect_uri optional Type: array of urls (one for each client) | Where to redirect the client when
|
Logout Parameters for triggering logout with the plugin and the actions to take on logout. | |
Form Parameter | Description |
config.logout_query_arg optional Type: string | The request query argument that activates the logout. |
config.logout_post_arg optional Type: string | The request body argument that activates the logout. |
config.logout_uri_suffix optional Type: string | The request URI suffix that activates the logout. |
config.logout_methods optional Type: array of string elements | The request methods that can activate the logout:
|
config.logout_revoke optional Type: boolean Default value: false | Revoke tokens as part of the logout. |
config.logout_revoke_access_token optional Type: boolean Default value: true | Revoke the access token as part of the logout. |
config.logout_revoke_refresh_token optional Type: boolean Default value: true | Revoke the refresh token as part of the logout. |
config.logout_redirect_uri optional Type: array of urls (one for each client) | Where to redirect the client after the logout. |
Unauthorized Parameters for how to handle unauthorized requests. | |
Form Parameter | Description |
config.unauthorized_redirect_uri optional Type: array of urls (one for each client) | Where to redirect the client on unauthorized requests. |
config.unauthorized_error_message optional Type: string Default value: “Forbidden” | The error message for the unauthorized requests (when not using the redirection). |
Forbidden Parameters for how to handle forbidden requests. | |
Form Parameter | Description |
config.forbidden_redirect_uri optional Type: array of urls (one for each client) | Where to redirect the client on forbidden requests. |
config.forbidden_error_message optional Type: string Default value: “Forbidden” | The error message for the forbidden requests (when not using the redirection). |
config.forbidden_destroy_session optional Type: boolean Default value: true | Destroy the possible session for the forbidden requests. |
Errors Parameters for how to handle unexpected errors. | |
Form Parameter | Description |
config.unexpected_redirect_uri optional Type: array of urls (one for each client) | Where to redirect the client when unexpected errors happen with the requests. |
config.display_errors optional Type: boolean Default value: false | Display errors on failure responses. |
Authorization Cookie Parameters used during authorization code flow for verification and preserving settings. | |
Form Parameter | Description |
config.authorization_cookie_name optional Type: string Default value: “authorization” | The authorization cookie name. |
config.authorization_cookie_lifetime optional Type: integer Default value: 600 | The authorization cookie lifetime in seconds. |
config.authorization_cookie_path optional Type: string Default value: ”/” | The authorization cookie Path flag. |
config.authorization_cookie_domain optional Type: string | The authorization cookie Domain flag. |
config.authorization_cookie_samesite optional Type: string Default value: “off” | Controls whether a cookie is sent with cross-origin requests, providing some protection against cross-site request forgery attacks:
|
config.authorization_cookie_httponly optional Type: boolean Default value: true | Forbids JavaScript from accessing the cookie, for example, through the |
config.authorization_cookie_secure optional Type: boolean Default value: (from the request scheme) | Cookie is only sent to the server when a request is made with the https: scheme (except on localhost), and therefore is more resistant to man-in-the-middle attacks. |
Session Cookie Parameters used with the session cookie authentication. | |
Form Parameter | Description |
config.session_cookie_name optional Type: string Default value: “session” | The session cookie name. |
config.session_cookie_lifetime optional Type: integer Default value: 3600 | The session cookie lifetime in seconds. |
config.session_cookie_idletime optional Type: integer | The session cookie idle time in seconds. |
config.session_cookie_renew optional Type: integer Default value: 600 | The session cookie renew time. |
config.session_cookie_path optional Type: string Default value: ”/” | The session cookie Path flag. |
config.session_cookie_domain optional Type: string | The session cookie Domain flag. |
config.session_cookie_samesite optional Type: string Default value: “Lax” | Controls whether a cookie is sent with cross-origin requests, providing some protection against cross-site request forgery attacks:
|
config.session_cookie_httponly optional Type: boolean Default value: true | Forbids JavaScript from accessing the cookie, for example, through the |
config.session_cookie_secure optional Type: boolean Default value: (from the request scheme) | Cookie is only sent to the server when a request is made with the https: scheme (except on localhost), and therefore is more resistant to man-in-the-middle attacks. |
config.session_cookie_maxsize optional Type: integer Default value: 4000 | The maximum size of each cookie chunk in bytes. |
Session Settings | |
Form Parameter | Description |
config.session_secret optional Type: string Default value: (with database, or traditional mode, the value is auto-generated and stored along the issuer discovery information in the database) | The session secret. This field is referenceable, which means it can be securely stored as a secret in a vault. References must follow a specific format. If keyring database encryption is enabled, this value will be encrypted. |
config.disable_session optional Type: array of string elements | Disable issuing the session cookie with the specified grants:
|
config.session_strategy optional Type: string Default value: “default” | The session strategy:
|
config.session_compressor optional Type: string Default value: “default” | The session strategy:
|
config.session_storage optional Type: string Default value: “cookie” | The session storage for session data:
|
config.reverify optional Type: boolean Default value: false | Specifies whether to always verify tokens stored in the session. |
Session Settings for Memcached | |
Form Parameter | Description |
config.session_memcache_prefix optional Type: string Default value: “sessions” | The memcached session key prefix. |
config.session_memcache_socket optional Type: string | The memcached unix socket path. |
config.session_memcache_host optional Type: string Default value: “127.0.0.1” | The memcached host. |
config.session_memcache_port optional Type: integer Default value: 11211 | The memcached port. |
Session Settings for Redis | |
Form Parameter | Description |
config.session_redis_prefix optional Type: string Default value: “sessions” | The Redis session key prefix. |
config.session_redis_socket optional Type: string | The Redis unix socket path. |
config.session_redis_host optional Type: string Default value: “127.0.0.1” | The Redis host |
config.session_redis_port optional Type: integer Default value: 6379 | The Redis port. |
config.session_redis_username optional Type: string | Username to use for Redis connection when the This field is referenceable, which means it can be securely stored as a secret in a vault. References must follow a specific format. |
config.session_redis_password optional Type: string Default value: (from kong) | Password to use for Redis connection when the This field is referenceable, which means it can be securely stored as a secret in a vault. References must follow a specific format. If keyring database encryption is enabled, this value will be encrypted. |
config.session_redis_auth optional Type: string Default value: (from kong) | Password to use for Redis connection when the If keyring database encryption is enabled, this value will be encrypted. |
config.session_redis_connect_timeout optional Type: integer Default value: (from kong) | The Redis connection timeout in milliseconds. |
config.session_redis_read_timeout optional Type: integer Default value: (from kong) | The Redis read timeout in milliseconds. |
config.session_redis_send_timeout optional Type: integer Default value: (from kong) | The Redis send timeout in milliseconds. |
config.session_redis_ssl optional Type: boolean Default value: false | Use SSL/TLS for Redis connection. |
config.session_redis_ssl_verify optional Type: boolean Default value: false | Verify Redis server certificate. |
config.session_redis_server_name optional Type: string | The SNI used for connecting the Redis server. |
config.session_redis_cluster_nodes optional Type: array of host records | The Redis cluster node host. Takes an array of host records, with either |
config.session_redis_cluster_maxredirections optional Type: integer | The Redis cluster maximum redirects. |
Endpoints Parameters normally not needed as the endpoints are discovered. | |
Form Parameter | Description |
config.authorization_endpoint optional Type: url Default value: (discovered uri) | The authorization endpoint. |
config.token_endpoint optional Type: url Default value: (discovered uri) | The token endpoint. |
config.introspection_endpoint optional Type: url Default value: (discovered uri) | The introspection endpoint. |
config.revocation_endpoint optional Type: url Default value: (discovered uri) | The revocation endpoint. |
config.userinfo_endpoint optional Type: url Default value: (discovered uri) | The user info endpoint. |
config.end_session_endpoint optional Type: url Default value: (discovered uri) | The end session endpoint. |
config.token_exchange_endpoint optional Type: url Default value: (discovered uri) | The token exchange endpoint. |
Endpoint Authentication Parameters normally not needed as the client authentication can be specified for the client. | |
Form Parameter | Description |
config.token_endpoint_auth_method optional Type: string Default value: (see: config.client_auth) | The token endpoint authentication method:
|
config.introspection_endpoint_auth_method optional Type: string Default value: (see: config.client_auth) | The introspection endpoint authentication method:
|
config.revocation_endpoint_auth_method optional Type: string Default value: (see: config.client_auth) | The revocation endpoint authentication method:
|
Discovery Endpoint Arguments | |
Form Parameter | Description |
config.discovery_headers_names optional Type: array of string elements | Extra header names passed to the discovery endpoint. |
config.discovery_headers_values optional Type: array of string elements | Extra header values passed to the discovery endpoint. |
Authorization Endpoint Arguments | |
Form Parameter | Description |
config.response_mode optional Type: string Default value: “query” | The response mode passed to the authorization endpoint:
|
config.response_type optional Type: array of string elements Default value: [“code”] | The response type passed to the authorization endpoint. |
config.scopes optional Type: array of string elements Default value: [“openid”] | The scopes passed to the authorization and token endpoints. |
config.audience optional Type: array of string elements | The audience passed to the authorization endpoint. |
config.redirect_uri optional Type: array of urls (one for each client) Default value: (request uri) | The redirect URI passed to the authorization and token endpoints. |
config.authorization_query_args_names optional Type: array of string elements | Extra query argument names passed to the authorization endpoint. |
config.authorization_query_args_values optional Type: array of string elements | Extra query argument values passed to the authorization endpoint. |
config.authorization_query_args_client optional Type: array of string elements | Extra query arguments passed from the client to the authorization endpoint. |
Token Endpoint Arguments | |
Form Parameter | Description |
config.token_headers_names optional Type: array of string elements | Extra header names passed to the token endpoint. |
config.token_headers_values optional Type: array of string elements | Extra header values passed to the token endpoint. |
config.token_headers_client optional Type: array of string elements | Extra headers passed from the client to the token endpoint. |
config.token_post_args_names optional Type: array of string elements | Extra post argument names passed to the token endpoint. |
config.token_post_args_values optional Type: array of string elements | Extra post argument values passed to the token endpoint. |
config.token_post_args_client optional Type: array of string elements | Extra post arguments passed from the client to the token endpoint. |
Token Endpoint Response Headers Parameters for an uncommon use case of sending certain token endpoint headers to the downstream client. | |
Form Parameter | Description |
config.token_headers_replay Type: array of string elements | The names of token endpoint response headers to forward to the downstream client. |
config.token_headers_prefix Type: string | Add a prefix to the token endpoint response headers before forwarding them to the downstream client. |
config.token_headers_grants Type: array of string elements | Enable the sending of the token endpoint response headers only with certain granst:
|
Introspection Endpoint Arguments | |
Form Parameter | Description |
config.introspection_hint optional Type: string Default value: “access_token” | Introspection hint parameter value passed to the introspection endpoint. |
config.introspection_accept optional Type: string Default value: “application/json” | The value of
|
config.introspection_headers_names optional Type: array of string elements | Extra header names passed to the introspection endpoint. |
config.introspection_headers_values optional Type: array of string elements | Extra header values passed to the introspection endpoint. |
config.introspection_headers_client optional Type: array of string elements | Extra headers passed from the client to the introspection endpoint. |
config.introspection_post_args_names optional Type: array of string elements | Extra post argument names passed to the introspection endpoint. |
config.introspection_post_args_values optional Type: array of string elements | Extra post argument values passed to the introspection endpoint. |
config.introspection_post_args_client optional Type: array of string elements | Extra post arguments passed from the client to the introspection endpoint. |
User Info Endpoint Arguments | |
Form Parameter | Description |
config.userinfo_accept optional Type: string Default value: “application/json” | The value of
|
config.userinfo_headers_names optional Type: array of string elements | Extra header names passed to the user info endpoint. |
config.userinfo_headers_values optional Type: array of string elements | Extra header values passed to the user info endpoint. |
config.userinfo_headers_client optional Type: array of string elements | Extra headers passed from the client to the user info endpoint. |
config.userinfo_query_args_names optional Type: array of string elements | Extra query argument names passed to the user info endpoint. |
config.userinfo_query_args_values optional Type: array of string elements | Extra query argument values passed to the user info endpoint. |
config.userinfo_query_args_client optional Type: array of string elements | Extra query arguments passed from the client to the user info endpoint. |
HTTP Client Parameters for generic settings for the HTTP client when the plugin needs to interact with the identity provider. | |
Form Parameter | Description |
config.keepalive optional Type: boolean Default value: true | Use keepalive with the HTTP client. |
config.ssl_verify optional Type: boolean Default value: false | Verify identity provider server certificate. |
config.timeout optional Type: integer Default value: 10000 | Network IO timeout in milliseconds. |
config.http_version optional Type: number Default value: 1.1 | The HTTP version used for the requests by this plugin:
|
HTTP Client Proxy Settings Parameters only needed if the HTTP(S) requests to identity provider need to go through a proxy server. | |
Form Parameter | Description |
config.http_proxy optional Type: url | The HTTP proxy |
config.http_proxy_authorization optional Type: string | The HTTP proxy authorization. |
config.https_proxy optional Type: url | The HTTPS proxy |
config.https_proxy_authorization optional Type: string | The HTTPS proxy authorization. |
config.no_proxy optional Type: array of string elements | Do not use proxy with these hosts. |
Cache TTLs | |
Form Parameter | Description |
config.cache_ttl optional Type: integer Default value: 3600 | The default cache ttl in seconds that is used in case the cached object does not specify the expiry. |
config.cache_ttl_max optional Type: integer | The maximum cache ttl in seconds (enforced). |
config.cache_ttl_min optional Type: integer | The minimum cache ttl in seconds (enforced). |
config.cache_ttl_neg optional Type: integer Default value: (derived from Kong configuration) | The negative cache ttl in seconds. |
config.cache_ttl_resurrect optional Type: integer Default value: (derived from Kong configuration) | The resurrection ttl in seconds. |
Cache Settings for the Endpoints | |
Form Parameter | Description |
config.cache_tokens optional Type: boolean Default value: true | Cache the token endpoint requests. |
config.cache_tokens_salt optional Type: string Default value: (auto generated) | Salt used for generating the cache key that us used for caching the token endpoint requests.
|
config.cache_introspection optional Type: boolean Default value: true | Cache the introspection endpoint requests. |
config.cache_token_exchange optional Type: boolean Default value: true | Cache the token exchange endpoint requests. |
config.cache_user_info optional Type: boolean Default value: true | Cache the user info requests. |
config.resolve_distributed_claims optional Type: boolean Default value: false | Distributed claims are represented by the |
Records
In the above parameter list, two configuration settings used an array of records as a data type:
config.client_jwk
: array of JWK records (one for each client)config.session_redis_cluster_nodes
: array of host records, either as IP addresses or hostnames, and their ports.
Below are descriptions of the record types.
JWK Record
The JSON Web Key (JWK) record is specified in RFC7571. This record is used with the config.client_jwk
when using private_key_jwk
client authentication.
Here is an example of JWK record generated by the plugin itself (see: JSON Web Key Set:
{
"kid": "B2FxBJ8G_e61tnZEfaYpaMLjswjNO3dbVEQhR7-i_9s",
"kty": "RSA",
"alg": "RS256",
"use": "sig"
"e": "AQAB",
"n": "…",
"d": "…",
"p": "…",
"q": "…",
"dp": "…",
"dq": "…",
"qi": "…"
}
Host Record
The Host record used with the config.session_redis_cluster_nodes
is simple. It contains ip
or host
, and the port
where the port
defaults to 6379
.
Here is an example of Host the record:
{
"ip": "127.0.0.1"
"port": 6379
}
Admin API
The OpenID Connect plugin extends the Kong Admin API with a few endpoints.
Discovery Cache
When configuring the plugin using config.issuer
, the plugin will store the fetched discovery information to the Kong database, or in the worker memory with Db-less.
Discovery Cache Object
{
"id": "<uuid>",
"issuer": "<config.issuer>"
"created_at": <timestamp>,
"configuration": {
<discovery>
},
"keys": [
<keys>
]
}
List All Discovery Cache Objects
/openid-connect/issuers
Response
HTTP 200 OK
{
"data": [{
"id": "<uuid>",
"issuer": "<config.issuer>"
"created_at": <timestamp>,
"configuration": {
<discovery>
},
"keys": [
<keys>
]
}],
"next": null
}
Retrieve Discovery Cache Object
/openid-connect/issuers/{issuer or id}
Attributes | Description |
---|---|
issuer or id required | The unique identifier or the value of config.issuer |
Response
HTTP 200 OK
{
"id": "<uuid>",
"issuer": "<config.issuer>"
"created_at": <timestamp>,
"configuration": {
<discovery>
},
"keys": [
<keys>
]
}
Delete All Discovery Cache Objects
/openid-connect/issuers
Response
HTTP 204 No Content
Note: The automatically generated session secret (that can be overridden with the
config.session_secret
) is stored with the discovery cache objects. Deleting discovery cache objects will invalidate all the sessions created with the associated secret.
Delete Discovery Cache Object
/openid-connect/issuers/{issuer or id}
Attributes | Description |
---|---|
issuer or id required | The unique identifier or the value of config.issuer |
Response
HTTP 204 No Content
JSON Web Key Set
When the OpenID Connect client (the plugin) is set to communicate with the identity provider endpoints using private_key_jwt
, the plugin needs to use public key cryptography. Thus, the plugin needs to generate the needed keys. Identity provider on the other hand has to verify that the assertions used for the client authentication.
The plugin will automatically generate the key pairs for the different algorithms. It will also publish the public keys with the admin api where the identity provider could fetch them.
{
"keys": [{
<keys>
}]
}
Retrieve JWKS
/openid-connect/jwks
This endpoint will return a standard JWK Set document with the private keys stripped out.
Response
HTTP 200 OK
{
"keys": [{
<keys>
}]
}
Rotate JWKS
/openid-connect/jwks
Deleting JWKS will also cause auto-generation of a new JWK set, so DELETE
will actually cause a key rotation.
Response
HTTP 204 No Content
Preparations
The OpenID Connect plugin relies in most cases on a 3rd party identity provider. In this section, we explain configuration of Keycloak and Kong.
All the *.test
domains in the following examples point to the localhost
(127.0.0.1
and/or ::1
).
Keycloak Configuration
We use Keycloak as the identity provider in the following examples, but the steps will be similar in other standard identity providers. If you encounter difficulties during this phase, please refer to the Keycloak documentation.
Create a confidential client
kong
withprivate_key_jwt
authentication and point the Keycloak to download the public keys from the OpenID Connect Plugin JWKS endpoint:
Create another confidential client
service
withclient_secret_basic
authentication, and the secret ofcf4c655a-0622-4ce6-a0de-d3353ef0b714
(Keycloak auto-generates one), and enable the client credentials grant for the client:
Create verified user
john
with the non-temporary passworddoe
that we can use with the password grant:
Alternatively you can download the exported Keycloak configuration, and use it to configure the Keycloak. Please refer to Keycloak import documentation for more information.
You need to modify Keycloak standalone.xml
configuration file, and change the socket binding from:
<socket-binding name="https" port="${jboss.https.port:8443}"/>
to
<socket-binding name="https" port="${jboss.https.port:8440}"/>
The Keycloak default https
port conflicts with the default Kong TLS proxy port, and that can be a problem if both are started on a single host.
Kong Configuration
Create a Service
http -f put :8001/services/openid-connect url=http://httpbin.org/anything
HTTP/1.1 200 OK
{
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd",
"name": "openid-connect",
"protocol": "http",
"host": "httpbin.org",
"port": 80,
"path": "/anything"
}
Create a Route
http -f put :8001/services/openid-connect/routes/openid-connect paths=/
HTTP/1.1 200 OK
{
"id": "ac1e86bd-4bce-4544-9b30-746667aaa74a",
"name": "openid-connect",
"paths": [ "/" ]
}
Create a Plugin
You may execute this before patching the plugin (as seen on following examples) to reset the plugin configuration.
http -f put :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
name=openid-connect \
service.name=openid-connect \
config.issuer=http://keycloak.test:8080/auth/realms/master \
config.client_id=kong \
config.client_auth=private_key_jwt
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"issuer": "http://keycloak.test:8080/auth/realms/master",
"client_id": [ "kong" ],
"client_auth": [ "private_key_jwt" ]
}
}
Also, check the discovery cache:
http :8001/openid-connect/issuers
. It should contain Keycloak OpenID Connect discovery document, and the keys.
Summary
At this point we have:
- Created a Service
- Routed traffic to the service
- Enabled OpenID Connect plugin on the service
Follow up on next sections to enable OpenID Connect plugin for specific grants or flows.
Authentication
Before you proceed, check that you have done the preparations.
We use HTTPie to execute the examples. The output is stripped for a better readability. httpbin.org is used as an upstream service.
Using Admin API is convenient when testing the plugin, but similar configs can be done in declarative format as well.
When plugin is configured with multiple grants / flows there is a hard-coded search order for the credentials:
- Session Authentication
- JWT Access Token Authentication
- Kong OAuth Token Authentication
- Introspection Authentication
- User Info Authentication
- Refresh Token Grant
- Password Grant
- Client Credentials Grant
- Authorization Code Flow
In case plugin finds credentials, it will stop searching other credentials. Some grants may use the same credentials, in other words, both password and client credentials grants can use credentials from basic authentication header.
Because the httpbin.org is used as an upstream service, it is highly recommend that you do not run these usage examples with a production identity provider as there is great a chance of leaking information. Also the examples below use the plain HTTP protocol that you should never use in production. The choices here are for simplicity.
Authorization Code Flow
The authorization code flow is the three-legged OAuth/OpenID Connect flow. The sequence diagram below, describes the participants, and their interactions for this usage scenario, including the use of session cookies:
Patch the Plugin
Let’s patch the plugin that we created in the Kong configuration step:
- We want to only use the authorization code flow and the session authentication.
- We want to set the response mode to
form_post
so that authorization codes won’t get logged to the access logs. - We want to preserve the original request query arguments over the authorization code flow redirections.
- We want to redirect the client to original request url after the authorization code flow so that the
POST
request (because ofform_post
) is turned to theGET
request, and the browser address bar is updated with the original request query arguments. - We don’t want to include any tokens in the browser address bar.
Reset the plugin configuration before patching.
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.auth_methods=authorization_code \
config.auth_methods=session \
config.response_mode=form_post \
config.preserve_query_args=true \
config.login_action=redirect \
config.login_tokens=
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [
"authorization_code",
"session"
],
"login_action": "redirect",
"preserve_query_args": true,
"login_tokens": null
}
}
Test the Authorization Code Flow
Open the Service Page with some query arguments:
open http://service.test:8000/?hello=world
See that the browser is redirected to the Keycloak login page:
You may examine the query arguments passed to Keycloak with the browser developer tools.
And finally you will be presented a response from httpbin.org:
- Done.
It looks rather simple from the user point of view, but what really happened is described in the diagram above.
Password Grant
Password grant is a legacy authentication grant. The password grant is a less secure way to authenticate the end users than the authorization code flow. For example, the passwords get shared with 3rd parties. The grant is rather simple though:
Patch the Plugin
Let’s patch the plugin that we created in the Kong configuration step:
- We want to only use the password grant.
- We want to search credentials for password grant from the headers only.
Reset the plugin configuration before patching.
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.auth_methods=password \
config.password_param_type=header
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [ "password" ],
"password_param_type": [ "header" ]
}
}
Test the Password Grant
Request the service with basic authentication credentials created in the Keycloak configuration step:
http -v -a john:doe :8000
GET / HTTP/1.1
Authorization: Basic BEkg3bHT0ERXFmKr1qelBQYrLBeHb5Hr
HTTP/1.1 200 OK
{
"headers": {
"Authorization": "Bearer <access-token>"
},
"method": "GET"
}
Done.
If you make another request using the same credentials, you should see that Kong adds less latency to the request as it has cached the token endpoint call to Keycloak.
Client Credentials Grant
Client credentials grant is almost the same as the password grant, but the biggest difference with the Kong OpenID Connect plugin is that the plugin itself does not try to authenticate. It just forwards the credentials passed by the client to the identity server’s token endpoint. The client credentials grant is visualized below:
Patch the Plugin
Let’s patch the plugin that we created in the Kong configuration step:
- We want to only use the client credentials grant.
- We want to search credentials for client credentials from the headers only.
Reset the plugin configuration before patching.
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.auth_methods=client_credentials \
config.client_credentials_param_type=header
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [ "client_credentials" ],
"client_credentials_param_type": [ "header" ]
}
}
Test the Client Credentials Grant
Request the service with client credentials created in the Keycloak configuration step:
http -v -a service:cf4c655a-0622-4ce6-a0de-d3353ef0b714 :8000
GET / HTTP/1.1
Authorization: Basic c2VydmljZTpjZjRjNjU1YS0wNjIyLTRjZTYtYTBkZS1kMzM1M2VmMGI3MTQ=
HTTP/1.1 200 OK
{
"headers": {
"Authorization": "Bearer <access-token>"
},
"method": "GET"
}
Done.
If you make another request using the same credentials, you should see that Kong adds less latency to the request as it has cached the token endpoint call to Keycloak.
Refresh Token Grant
The refresh token grant can be used when the client has a refresh token available. There is a caveat with this: identity providers in general only allow refresh token grant to be executed with the same client that originally got the refresh token, and if there is a mismatch, it may not work. The mismatch is likely when Kong OpenID Connect is configured to use one client, and the refresh token is retrieved with another. The grant itself is very similar to password grant and client credentials grant:
Patch the Plugin
Let’s patch the plugin that we created in the Kong configuration step:
- We want to only use the refresh token grant, but we also enable the password grant for demoing purposes
- We want to search the refresh token for the refresh token grant from the headers only.
- We want to pass refresh token from the client in
Refresh-Token
header. - We want to pass refresh token to upstream in
Refresh-Token
header.
Reset the plugin configuration before patching.
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.refresh_token_param_name=refresh_token \
config.refresh_token_param_type=header \
config.auth_methods=refresh_token \
config.auth_methods=password \
config.upstream_refresh_token_header=refresh_token
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [
"refresh_token",
"password"
],
"refresh_token_param_name": "refresh_token",
"refresh_token_param_type": [ "header" ],
"upstream_refresh_token_header": "refresh_token"
}
}
The config.auth_methods
and config.upstream_refresh_token_header
are only enabled for demoing purposes so that we can get a refresh token with:
http -a john:doe :8000 | jq -r '.headers."Refresh-Token"'
Output:
<refresh-token>
We can use the output in Refresh-Token
header.
Test the Refresh Token Grant
Request the service with a bearer token:
http -v :8000 Refresh-Token:$(http -a john:doe :8000 | \
jq -r '.headers."Refresh-Token"')
or
http -v :8000 Refresh-Token:"<refresh-token>"
GET / HTTP/1.1
Refresh-Token: <refresh-token>
HTTP/1.1 200 OK
{
"headers": {
"Authorization": "Bearer <access-token>",
"Refresh-Token": "<refresh-token>"
},
"method": "GET"
}
Done.
JWT Access Token Authentication
For legacy reasons, the stateless JWT Access Token
authentication is named bearer
with the Kong OpenID Connect plugin (see: config.auth_methods
). Stateless authentication basically means the signature verification using the identity provider published public keys and the standard claims’ verification (such as exp
(or expiry)). The client may have received the token directly from the identity provider or by other means. It is simple:
Patch the Plugin
Let’s patch the plugin that we created in the Kong configuration step:
- We want to only use the bearer authentication, but we also enable the password grant for demoing purposes
- We want to search the bearer token for the bearer authentication from the headers only.
Reset the plugin configuration before patching.
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.bearer_token_param_type=header \
config.auth_methods=bearer \
config.auth_methods=password # only enabled for demoing purposes
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [
"bearer",
"password"
],
"bearer_token_param_type": [ "header" ]
}
}
The password grant is enabled so that we can get a JWT access token that we can use to show how the JWT access token authentication works. That is: we need a token. One way to get a JWT access token is to issue the following call (we use jq to filter the response):
http -a john:doe :8000 | jq -r .headers.Authorization
Output:
Bearer <access-token>
We can use the output in Authorization
header.
Test the JWT Access Token Authentication
Request the service with a bearer token:
http -v :8000 Authorization:"$(http -a john:doe :8000 | \
jq -r .headers.Authorization)"
or
http -v :8000 Authorization:"Bearer <access-token>"
GET / HTTP/1.1
Authorization: Bearer <access-token>
HTTP/1.1 200 OK
{
"headers": {
"Authorization": "Bearer <access-token>"
},
"method": "GET"
}
Done.
Introspection Authentication
As with JWT Access Token Authentication), the introspection authentication relies on a bearer token that the client has already gotten from somewhere. The difference to stateless JWT authentication is that the plugin needs to call the introspection endpoint of the identity provider to find out whether the token is valid and active. This makes it possible to issue opaque tokens to the clients.
Patch the Plugin
Let’s patch the plugin that we created in the Kong configuration step:
- We want to only use the introspection authentication, but we also enable the password grant for demoing purposes
- We want to search the bearer token for the introspection from the headers only.
Reset the plugin configuration before patching.
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.bearer_token_param_type=header \
config.auth_methods=introspection \
config.auth_methods=password # only enabled for demoing purposes
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [
"introspection",
"password"
],
"bearer_token_param_type": [ "header" ]
}
}
Test the Introspection Authentication
Request the service with a bearer token:
http -v :8000 Authorization:"$(http -a john:doe :8000 | \
jq -r .headers.Authorization)"
or
http -v :8000 Authorization:"Bearer <access-token>"
GET / HTTP/1.1
Authorization: Bearer <access-token>
HTTP/1.1 200 OK
{
"headers": {
"Authorization": "Bearer <access-token>"
},
"method": "GET"
}
Done.
User Info Authentication
The user info authentication uses OpenID Connect standard user info endpoint to verify the access token. In most cases it is preferable to use Introspection Authentication as that is meant for retrieving information from the token itself, whereas the user info endpoint is meant for retrieving information about the user for whom the token was given. The sequence diagram below looks almost identical to introspection authentication:
Patch the Plugin
Let’s patch the plugin that we created in the Kong configuration step:
- We want to only use the user info authentication, but we also enable the password grant for demoing purposes
- We want to search the bearer token for the user info from the headers only.
Reset the plugin configuration before patching.
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.bearer_token_param_type=header \
config.auth_methods=userinfo \
config.auth_methods=password # only enabled for demoing purposes
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [
"userinfo",
"password"
],
"bearer_token_param_type": [ "header" ]
}
}
Test the User Info Authentication
Request the service with a bearer token:
http -v :8000 Authorization:"$(http -a john:doe :8000 | \
jq -r .headers.Authorization)"
or
http -v :8000 Authorization:"Bearer <access-token>"
GET / HTTP/1.1
Authorization: Bearer <access-token>
HTTP/1.1 200 OK
{
"headers": {
"Authorization": "Bearer <access-token>"
},
"method": "GET"
}
Done.
Kong OAuth Token Authentication
The OpenID Connect plugin can also verify the tokens issued by Kong OAuth 2.0 Plugin. This is very similar to 3rd party identity provider issued JWT access token authentication or introspection authentication:
Prepare Kong OAuth Application
Create a Consumer:
http -f put :8001/consumers/jane
Create Kong OAuth Application for the consumer:
http -f put :8001/consumers/jane/oauth2/client \
name=demo \
client_secret=secret \
hash_secret=true
Create a Route:
http -f put :8001/routes/auth paths=/auth
Apply OAuth plugin to the Route:
http -f put :8001/plugins/7cdeaa2d-5faf-416d-8df5-533d1e4cd2c4 \
name=oauth2 \
route.name=auth \
config.global_credentials=true \
config.enable_client_credentials=true
Test the token endpoint:
https -f --verify no post :8443/auth/oauth2/token \
client_id=client \
client_secret=secret \
grant_type=client_credentials
HTTP/1.1 200 OK
{
"access_token": "<access-token>",
"expires_in": 7200,
"token_type": "bearer"
}
At this point we should be able to retrieve a new access token with:
https -f --verify no post :8443/auth/oauth2/token \
client_id=client \
client_secret=secret \
grant_type=client_credentials | \
jq -r .access_token
Output:
<access-token>
Patch the Plugin
Let’s patch the plugin that we created in the Kong configuration step:
- We want to only use the Kong OAuth authentication
- We want to search the bearer token for the Kong OAuth authentication from the headers only.
Reset the plugin configuration before patching.
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.auth_methods=kong_oauth2 \
config.bearer_token_param_type=header
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [ "kong_oauth2" ],
"bearer_token_param_type": [ "header" ]
}
}
Test the Kong OAuth Token Authentication
Request the service with Kong OAuth token:
http -v :8000 Authorization:"Bearer $(https -f --verify no \
post :8443/auth/oauth2/token \
client_id=client \
client_secret=secret \
grant_type=client_credentials | \
jq -r .access_token)"
or
http -v :8000 Authorization:"Bearer <access-token>"
GET / HTTP/1.1
Authorization: Bearer <access-token>
HTTP/1.1 200 OK
{
"headers": {
"Authorization": "Bearer <access-token>",
"X-Consumer-Id": "<consumer-id>",
"X-Consumer-Username": "jane"
},
"method": "GET"
}
Done.
Session Authentication
Kong OpenID Connect plugin can issue a session cookie that can be used for further session authentication. To make OpenID Connect issue a session cookie, you need to first authenticate with one of the other grant / flows described above. In authorization code flow we already demonstrated session authentication when we used the redirect login action. The session authentication is described below:
Patch the Plugin
Let’s patch the plugin that we created in the Kong configuration step:
- We want to only use the session authentication, but we also enable the password grant for demoing purposes
Reset the plugin configuration before patching.
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.auth_methods=session \
config.auth_methods=password # only enabled for demoing purposes
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [
"session",
"password"
]
}
}
Test the Session Authentication
Request the service with basic authentication credentials (created in the Keycloak configuration step), and store the session:
http -v -a john:doe --session=john :8000
GET / HTTP/1.1
Authorization: Basic BEkg3bHT0ERXFmKr1qelBQYrLBeHb5Hr
HTTP/1.1 200 OK
Set-Cookie: session=<session-cookie>; Path=/; SameSite=Lax; HttpOnly
{
"headers": {
"Authorization": "Bearer <access-token>"
},
"method": "GET"
}
Make request with a session cookie (stored above):
http -v --session=john :8000
GET / HTTP/1.1
Cookie: session=<session-cookie>
HTTP/1.1 200 OK
{
"headers": {
"Authorization": "Bearer <access-token>"
},
"method": "GET"
}
Done.
If you want to disable session creation with some grants, you can use the
config.disable_session
.
Authorization
Before you proceed, check that you have completed the preparations.
The OpenID Connect plugin has several features to do coarse grained authorization:
Claims Based Authorization
With claims verification, you have a couple of configuration options that all work the same and that can be used for the authorization:
config.scopes_claim
andconfig.scopes_required
config.audience_claim
andconfig.audience_required
config.groups_claim
andconfig.groups_required
config.roles_claim
andconfig.roles_required
The first configuration option, for example config.scopes_claim
, points to a source, from which the value is retrieved and checked against the value of the second configuration option, in this case config.scopes_required
.
Let’s take a look at a JWT access token:
Reset the plugin configuration before patching.
Patch the plugin to enable the password grant:
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.auth_methods=password
Retrieve the content of an access token:
http -a john:doe :8000 | jq -r .headers.Authorization
HTTP/1.1 200 OK
Bearer <access-token>
The signed JWT
<access-token>
(JWS) comes with three parts separated with a dot.
:<header>.<payload>.<signature>
(a JWS compact serialization format)We are interested with the
<payload>
, and you should have something similar to:eyJleHAiOjE2MjI1NTY3MTMsImF1ZCI6ImFjY291bnQiLCJ0eXAiOiJCZWFyZXIiLC
JzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIiwicHJlZmVycmVkX3VzZXJuYW1l
Ijoiam9obiIsImdpdmVuX25hbWUiOiJKb2huIiwiZmFtaWx5X25hbWUiOiJEb2UifQ
That can be base64 url decoded to the following
JSON
:{
"exp": 1622556713,
"aud": "account",
"typ": "Bearer",
"scope": "openid email profile",
"preferred_username": "john",
"given_name": "John",
"family_name": "Doe"
}
This payload may contain arbitrary claims, such as user roles and groups, but as we didn’t configure them in Keycloak, let’s just use the claims that we have. In this case we want to authorize against the values in
scope
claim.
Let’s patch the plugin that we created in the Kong configuration step:
- We want to only use the password grant for demonstration purposes.
- We require the value
openid
andemail
to be present inscope
claim of the access token.
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.auth_methods=password \
config.scopes_claim=scope \
config.scopes_required="openid email"
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [ "password" ],
"scopes_claim": [ "scope" ],
"scopes_required": [ "openid email" ]
}
}
Now let’s see if we can still access the service:
http -v -a john:doe :8000
GET / HTTP/1.1
Authorization: Basic BEkg3bHT0ERXFmKr1qelBQYrLBeHb5Hr
HTTP/1.1 200 OK
{
"headers": {
"Authorization": "Bearer <access-token>"
},
"method": "GET"
}
Works as expected, but let’s try to add another authorization:
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.audience_claim=aud \
config.audience_required=httpbin
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [ "password" ],
"audience_claim": [ "scope" ],
"audience_required": [ "httpbin" ]
}
}
As we know, the access token has "aud": "account"
, and that does not match with "httpbin"
, so the request should now be forbidden:
http -v -a john:doe :8000
HTTP/1.1 403 Forbidden
{
"message": "Forbidden"
}
A few words about config.scopes_claim
and config.scopes_required
(and the similar configuration options). You may have noticed that config.scopes_claim
is an array of string elements. Why? It is used to traverse the JSON when looking up a claim, take for example this imaginary payload:
{
"user": {
"name": "john",
"groups": [
"employee",
"marketing"
]
}
}
In this case you would probably want to use config.groups_claim
to point to groups
claim, but that claim is not a top-level claim, so you need to traverse there:
- Find the
user
claim and under it. - Find the the
groups
claim, and read the value:
{
"config": {
"groups_claim": [
"user",
"groups"
]
}
}
or
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.groups_claim=user \
config.groups_claim=groups
The value of a claim can be the following:
- a space separated string (such as
scope
claim usually is) - an JSON array of strings (such as the imaginary
groups
claim above) - a simple value, such as a
string
What about the config.groups_required
then? That is also an array?
That is correct, the required checks are arrays to allow logical and
/or
type of checks:
and
: use a space separated valuesor
: specify value(s) in separate array indices
For example:
{
"config": {
"groups_required": [
"employee marketing",
"super-admins"
]
}
}
or
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.groups_required="employee marketing" \
config.groups_required="super-admins"
The above means that a claim has to have:
employee
andmarketing
values in it, ORsuper-admins
value in it
ACL Plugin Authorization
The plugin can also be integrated with Kong ACL Plugin that provides access control functionality in form of allow and deny lists.
Please read the claims verification section for a basic information, as a lot of that applies here too.
Let’s first configure the OpenID Connect plugin for integration with the ACL plugin (please remove other authorization if enabled):
Reset the plugin configuration before patching.
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.auth_methods=password \
config.authenticated_groups_claim=scope
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [ "password" ],
"authorized_groups_claim": [ "scope" ]
}
}
Before we apply the ACL plugin, let’s try it once:
http -v -a john:doe :8000
HTTP/1.1 200 OK
{
"headers": {
"X-Authenticated-Groups": "openid, email, profile",
}
}
Interesting, the X-Authenticated-Groups
header was injected in a request. This means that we are all good to add the ACL plugin:
http -f put :8001/plugins/b238b64a-8520-4bbb-b5ff-2972165cf3a2 \
name=acl \
service.name=openid-connect \
config.allow=openid
Let’s test it again:
http -v -a john:doe :8000
HTTP/1.1 200 OK
Let’s make it forbidden by changing it to a deny-list:
http -f patch :8001/plugins/b238b64a-8520-4bbb-b5ff-2972165cf3a2 \
config.allow= \
config.deny=profile
And try again:
http -v -a john:doe :8000
HTTP/1.1 403 Forbidden
{
"message": "You cannot consume this service"
}
Consumer Authorization
The third option for authorization is to use Kong consumers and dynamically map from a claim value to a Kong consumer. This means that we restrict the access to only those that do have a matching Kong consumer. Kong consumers can have ACL groups attached to them and be further authorized with the Kong ACL Plugin.
As a remainder our token payload looks like this:
{
"exp": 1622556713,
"aud": "account",
"typ": "Bearer",
"scope": "openid email profile",
"preferred_username": "john",
"given_name": "John",
"family_name": "Doe"
}
Out of these the preferred_username
claim looks promising for consumer mapping. Let’s patch the plugin:
Reset the plugin configuration before patching.
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.auth_methods=password \
config.consumer_claim=preferred_username \
config.consumer_by=username
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [ "password" ],
"consumer_claim": [ "preferred_username" ],
"consumer_by": [ "username" ]
}
}
Before we proceed, let’s make sure we don’t have consumer john
:
http delete :8001/consumers/john
HTTP/1.1 204 No Content
Let’s try to access the service without a matching consumer:
http -a john:doe :8000
HTTP/1.1 403 Forbidden
{
"message": "Forbidden"
}
Now, let’s add the consumer:
http -f put :8001/consumers/john
HTTP/1.1 200 OK
{
"id": "<consumer-id>",
"username": "john"
}
Let’s try to access the service again:
http -a john:doe :8000
HTTP/1.1 200 OK
{
"headers": {
"Authorization": "Bearer <access-token>",
"X-Consumer-Id": "<consumer-id>",
"X-Consumer-Username": "john"
},
"method": "GET"
}
Nice, as you can see the plugin even added the X-Consumer-Id
and X-Consumer-Username
as request headers.
It is possible to make consumer mapping optional and non-authorizing by setting the
config.consumer_optional=true
.
Headers
Before you proceed, check that you have completed the preparations.
The OpenID Connect plugin can pass claim values, tokens, JWKs, and the session identifier to the upstream service in request headers, and to the downstream client in response headers. By default, the plugin passes an access token in Authorization: Bearer <access-token>
header to the upstream service (this can be controlled with config.upstream_access_token_header
). The claim values can be taken from:
- an access token,
- an id token,
- an introspection response, or
- a user info response
Let’s take a look for an access token payload:
{
"exp": 1622556713,
"aud": "account",
"typ": "Bearer",
"scope": "openid email profile",
"preferred_username": "john",
"given_name": "John",
"family_name": "Doe"
}
To pass the preferred_username
claim’s value john
to the upstream with an Authenticated-User
header, we need to patch our plugin:
Reset the plugin configuration before patching.
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.auth_methods=password \
config.upstream_headers_claims=preferred_username \
config.upstream_headers_names=authenticated_user
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [ "password" ],
"upstream_headers_claims": [ "preferred_username" ],
"upstream_headers_names": [ "authenticated_user" ]
}
}
Let’s see if it had any effect:
http -a john:doe :8000
HTTP/1.1 200 OK
{
"headers": {
"Authorization": "Bearer <access-token>",
"Authenticated-User": "john"
},
"method": "GET"
}
See the configuration parameters for other options.
Logout
The logout functionality is mostly useful together with session authentication that is mostly useful with authorization code flow.
As part of the logout, the OpenID Connect plugin implements several features:
- session invalidation
- token revocation
- relying party (RP) initiated logout
Let’s patch the OpenID Connect plugin to provide the logout functionality:
Reset the plugin configuration before patching.
http -f patch :8001/plugins/5f35b796-ced6-4c00-9b2a-90eef745f4f9 \
config.auth_methods=session \
config.auth_methods=password \
config.logout_uri_suffix=/logout \
config.logout_methods=POST \
config.logout_revoke=true
HTTP/1.1 200 OK
{
"id": "5f35b796-ced6-4c00-9b2a-90eef745f4f9",
"name": "openid-connect",
"service": {
"id": "5fa9e468-0007-4d7e-9aeb-49ca9edd6ccd"
},
"config": {
"auth_methods": [ "password", "session" ],
"logout_uri_suffix": "/logout",
"logout_methods": [ "POST" ],
"logout_revoke": true
}
}
Login and establish a session:
http -a john:doe --session=john :8000
HTTP/1.1 200 OK
Test that session authentication works:
http --session=john :8000
HTTP/1.1 200 OK
Logout, and follow the redirections:
http --session=john --follow -a john: post :8000/logout
HTTP/1.1 200 OK
We needed to pass
-a john:
as there seems to be a feature withHTTPie
that makes it to store the original basic authentication credentials in a session - not just the session cookies.
At this point the client has logged out from both Kong and the identity provider (Keycloak).
Check that the session is really gone:
http --session=john :8000
HTTP/1.1 401 Unauthorized
Debugging
The OpenID Connect plugin is pretty complex, and it has to integrate with a 3rd party identity provider. This makes it slightly more difficult to debug. If you have issues with the plugin or integration, try the following:
Set Kong log level to
debug
, and check the Kongerror.log
(you can filter it withopenid-connect
)KONG_LOG_LEVEL=debug kong restart
Set the Kong OpenID Connect plugin to display errors:
{
"config": {
"display_errors": true
}
}
Disable the Kong OpenID Connect plugin verifications and see if you get further, just for debugging purposes:
{
"config": {
"verify_nonce": false,
"verify_claims": false,
"verify_signature": false
}
}
See what kind of tokens the Kong OpenID Connect plugin gets:
{
"config": {
"login_action": "response",
"login_tokens": [ "tokens" ],
"login_methods": [
"password",
"client_credentials",
"authorization_code",
"bearer",
"introspection",
"userinfo",
"kong_oauth2",
"refresh_token",
"session"
]
}
}
With session related issues, you can try to store the session data in Redis
or memcache
as that will make the session cookie much smaller. It is rather common that big cookies do cause issues. You can also enable session compression.
Also try to eliminate indirection as that makes it easier to find out where the problem is. By indirection, we mean other gateways, load balancers, NATs, and such in front of Kong. If there is such, you may look at using:
- port maps
X-Forwarded-*
headers
Changelog
Kong Gateway 2.8.x (plugin version 2.2.1)
Added the
session_redis_username
andsession_redis_password
configuration parameters.Added the
resolve_distributed_claims
configuration parameter.The
client_id
,client_secret
,session_secret
,session_redis_username
, andsession_redis_password
configuration fields are now marked as referenceable, which means they can be securely stored as secrets in a vault. References must follow a specific format.
Kong Gateway 2.7.x (plugin version 2.2.0)
Starting with Kong Gateway 2.7.0.0, if keyring encryption is enabled, the
config.client_id
,config.client_secret
,config.session_auth
, andconfig.session_redis_auth
parameter values will be encrypted.Additionally, the
d
,p
,q
,dp
,dq
,qi
,oth
,r
,t
, andk
fields insideopenid_connect_jwks.previous[...].
andopenid_connect_jwks.keys[...]
will be marked as encrypted.