Extra Use Cases for Kong OIDC Plugin
Kong’s OIDC plugin is so powerful and complicated (It has nearly 200 parameters…) that it can do a lot more when users know what combination of configs they need to use. In today’s post, I will show you a few use cases that might help you use this plugin better.
Please note I was using the latest 2.4.1.1 version of Kong Gateway (Enterprise), some of the config might not be available in the version you are using.
Prerequisites:
- Kong Gateway (Enterprise)
- OIDC server is running. (Keycloak in my example) If you are not sure how to use keycloa, you can check my previous post
Use claim from IDP token to upstream header
If you want to map a value from IDP token to upstream header, you can use config.upstream_headers_names
and config.upstream_headers_claims
.
Let’s say we have below claim in our JWT token payload.
1 | { |
The goal is to map value to-upstream
to header kong-test
and send it to upstream server. We can set OIDC plugin as below. This is using password flow.
1 | curl --request POST \ |
When we call our api endpoint with username and password we should see below header sent in the request sent to upstream server.
1 | "Test-Kong": "to-upstream", |
If the value is an object. For example, if I want to pass the information of employee
to upstream in a header, it will be base64 encoded.
1 | { |
Let’s enable the plugin as below,
1 | curl --request POST \ |
Now when you authenticate, your upstream should have below header.
1 | "X-Employee-Info": [ |
Check Token received
Sometimes we might have issue setting up OIDC plugin but we don’t see a lot info from logs. For example in the log you can see kong failed to find the consumer for consumer mapping and you are pretty sure token should have this information. (This could happen when you forget to include a scope in your request so the claim does not get added.)
The best way to debug in this situations is to check the token sent back from your IDP. To do that, we need to set config.login_action=response
and config.login_tokens=tokens
.
Example:
Enable OIDC plugin with
authorization_code
flow.1
2
3
4
5
6
7
8
9
10curl --request POST \
--url http://kong.li.lan:8001/plugins \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data name=openid-connect \
--data config.issuer=https://<keycloak>/auth/realms/demo \
--data config.client_id=<client_id> \
--data config.client_secret=<client_secret> \
--data config.auth_methods=authorization_code \
--data config.login_action=response \
--data config.login_tokens=tokensUse browser to access
https://<kong_proxy>/<oidc_protected_route>
Log in and we will see the token from IDP.
Required Multiple Claims
If your application requires certain claim with certain value on the JWT token sent from your IDP, you can use below 4 pairs to validate those JWT tokens.
config.groups_claim
andconfig.groups_required
config.scopes_claim
andconfig.scopes_required
config.roles_claim
andconfig.roles_required
,config.audience_claim
andconfig.audience_required
The name of the parameter does not matter, you can them on any claims. There are some guide line about using them though.
- You can validate at most 4 claims at the same time.
- You can validate multiple values of the same claim in
or
andand
logic. - You can traverse array/object for the claim name.
For example, let’s say I will get below employee
claim on the JWT token.
1 | "employee": { |
Traverse claim array
If I only want to give access to an employee whose favourite beverage is coffee, I can enable OIDC plugin as below.
1 | curl --request POST \ |
As you can see I am setting "scopes_claim":["employee","favourites","beverage"]
as an array and config.scopes_required=coffee
. Kong will traverse JWT claim and verify if beverage
is the equal to coffee
. If the return JWT does not have beverage=coffee
, user will get HTTP/1.1 403 Forbidden
.
Validate multiple values for a particular claim
AND
Logic
If I want to give access to user who is in bothdefault
andit
group, we can enable OIDC plugin as below.1
2
3
4
5
6
7
8
9
10
11curl --request POST \
--url http://kong.li.lan:8001/plugins \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data name=openid-connect \
--data config.issuer=https://<keycloak>/auth/realms/demo \
--data config.client_id=<client_id> \
--data config.client_secret=<client_secret> \
--data config.auth_methods=password \
--data 'config.scopes_required=default it' \
--data config.scopes_claim=employee \
--data config.scopes_claim=groupsOR
logic
If I want to give access to user from eitherdefault
orit
group, we can enable OIDC plugin as below.1
2
3
4
5
6
7
8
9
10
11
12curl --request POST \
--url http://kong.li.lan:8001/plugins \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data name=openid-connect \
--data config.issuer=https://<keycloak>/auth/realms/demo \
--data config.client_id=<client_id> \
--data config.client_secret=<client_secret> \
--data config.auth_methods=password \
--data 'config.scopes_required=default' \
--data 'config.scopes_required=it' \
--data config.scopes_claim=employee \
--data config.scopes_claim=groups
The key is for config.scopes_required
, array indices is OR
logic and space separated on the same array indices is AND
logic.
Pass extra query argument to authoriazation endpoint
When you are using authorization code flow, unrelated query arguments on the redirect url will be removed. You can add extra query arguments in authorization endpoint query string with below settings.
Add dynamic value
Let’s say you want to pass a query argument to idp to specify who is accessing the server. For example, you can pass username or email to IDP by setting config.authorization_query_args_client
.
1 | curl --request POST \ |
After that, when we go to https://<kong_proxy>/<protected_route>?username=admin
We should see username is filled with admin
.
Add static value
If you want to add static query arguments, you can use config.authorization_query_args_names
and config.authorization_query_args_values
to add multiple value pairs.
1 | curl --request POST \ |
Now when we go to https://<kong_proxy>/<protected_route>
We should see user=demo
on the authorization url.
That’s all I want to share today. In my next post I will show you how to use client auth with OIDC.