Skip to content
This repository has been archived by the owner on Apr 18, 2024. It is now read-only.

OIDC Kong / Keycloak #23

Open
victorfunes opened this issue Oct 18, 2022 · 19 comments
Open

OIDC Kong / Keycloak #23

victorfunes opened this issue Oct 18, 2022 · 19 comments
Assignees

Comments

@victorfunes
Copy link

I am trying to use your plugin to connect keycloak 19.0.2 with kong 3.0.0, but the introspection step seems not to be working properly as Kong always returns when I try to access to an API:
{
"message": "Unauthorized"
}

When I execute the request for introspection manually from Postman, it works perfectly using basic authentication (client_id and client_secret as user and password in the header, and the token in the body), so my assumption is that Keycloak expects this structure of request.

With this purpose, I have configured the OIDC plugin (using Konga by the way) defining the value of the field "token endpoint auth method" as "client_secret_basic".

After doing this, when I try to access the API, in the logs I can see the message:

2022/10/18 07:47:48 [debug] 1378#0: *190 [lua] openidc.lua:515: call_token_endpoint(): request body for introspection endpoint call: client_secret=(my client secret)&token=(my token)&client_id=(my client id)

Apparently, client_secret_basic is behaving as client_secret_post including the client_id and client_secret in the body instead of sending this info in the header as Keycloak expects.

Am I doing something wrong?
Thanks in advance for your support.

@ruiengana
Copy link
Collaborator

ruiengana commented Oct 18, 2022 via email

@victorfunes
Copy link
Author

Thank you for your quick answer! I am sure I am missing something in the configuration, but I cannot find it.
I have changed it back to client_secret_post, and now I get the first error I got (this is why I tried to change to client_secret_basic):

2022/10/18 13:52:34 [error] 1379#0: *1098 [kong] init.lua:290 [oidc] /usr/local/share/lua/5.1/kong/plugins/oidc/utils.lua:122: header must be a string, client: 172.19.0.1, server: kong, request: "GET /api/welcome HTTP/1.1", host: "localhost:8000"
172.19.0.1 - - [18/Oct/2022:13:52:34 +0000] "GET /api/welcome HTTP/1.1" 500 42 "-" "PostmanRuntime/7.29.2"

@ruiengana
Copy link
Collaborator

ruiengana commented Oct 18, 2022 via email

@victorfunes
Copy link
Author

victorfunes commented Oct 19, 2022

I have the same configuration, but still get the same error.
¿Maybe it could be something related to the credentials of the Kong consumer? My config is as follows:
{
"created_at": 1666102576,
"tags": null,
"consumer": {
"id": "2db8f9ad-c4aa-4bae-97c3-3202dd8806a9"
},
"rsa_public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIj...(lalala)...QAB\n-----END PUBLIC KEY-----",
"secret": "oaF...(lalala)...DTdy",
"key": (Keycloak Realm RS256 Kid),
"algorithm": "RS256",
"id": "efeef11f-b844-4a5d-95fa-3b3027fe7d60"
}

@victorfunes
Copy link
Author

I copy here also the oidc plugin config for more clarity:

{
"created_at": 1665503433,
"name": "oidc",
"service": null,
"protocols": [
"grpc",
"grpcs",
"http",
"https"
],
"enabled": true,
"route": null,
"config": {
"timeout": null,
"realm": "MyRealm",
"validate_scope": "no",
"client_secret": "jHW...(lalala)...BQM",
"ssl_verify": "no",
"introspection_cache_ignore": "true",
"redirect_uri": null,
"response_type": "code",
"token_endpoint_auth_method": "client_secret_post",
"ignore_auth_filters": null,
"logout_path": "/logout",
"revoke_tokens_on_logout": "no",
"redirect_after_logout_uri": "/",
"redirect_after_logout_with_id_token_hint": "no",
"post_logout_redirect_uri": null,
"bearer_jwt_auth_allowed_auds": [
"account"
],
"discovery": "http://keycloak:8080/auth/realms/MyRealm/.well-known/openid-configuration",
"skip_already_auth_requests": "no",
"scope": "openid",
"session_secret": null,
"bearer_jwt_auth_enable": "yes",
"groups_claim": "groups",
"header_names": [],
"header_claims": [],
"disable_userinfo_header": "no",
"userinfo_header_name": "X-USERINFO",
"introspection_endpoint": "http://keycloak:8080/auth/realms/MyRealm/protocol/openid-connect/token/introspect",
"disable_access_token_header": "no",
"access_token_header_name": "X-Access-Token",
"access_token_as_bearer": "yes",
"disable_id_token_header": "no",
"id_token_header_name": "X-ID-Token",
"introspection_endpoint_auth_method": null,
"unauth_action": "deny",
"bearer_jwt_auth_signing_algs": [
"RS256"
],
"recovery_page_path": null,
"client_id": "MyClientId",
"filters": null,
"bearer_only": "yes",
"use_jwks": "no"
},
"consumer": null,
"tags": null,
"id": "bf1f6dec-85fb-4084-8311-9360d32f30e8"
}

@ruiengana
Copy link
Collaborator

ruiengana commented Oct 19, 2022 via email

@victorfunes
Copy link
Author

Ooops! Thank you for the clarification and your quick support!
I close the ticket, and please accept my apologies for the lack of knowledge.

@victorfunes
Copy link
Author

victorfunes commented Oct 20, 2022

Hi,
I reopen this point, as I have continued working on it and in the logs, I see the introspection call succeeds but kong answers:
{
"message": "An unexpected error occurred"
}

You can see the introspection success here:

2022/10/20 11:53:05 [debug] 1378#0: *865 [lua] openidc.lua:515: call_token_endpoint(): request body for introspection endpoint call: client_secret=DYC...p8u&client_id=Client&token=eyJ...
2022/10/20 11:53:05 [debug] 1378#0: *865 [lua] openidc.lua:434: openidc_configure_proxy(): openidc_configure_proxy : don't use http proxy
2022/10/20 11:53:05 [debug] 1378#0: *865 [lua] openidc.lua:533: call_token_endpoint(): introspection endpoint response: {"exp":1666266998,"iat":1666266698,"jti":"cce13bc7-bed1-466d-895e-9d1583040082","iss":"http://keycloak:8080/auth/realms/MyRealm","aud":"account","sub":"e5f73956-9753-4ade-aad1-115b34567fed","typ":"Bearer","azp":"Client","session_state":"77b...ce15","name":"Victor Funes","given_name":"Victor","family_name":"Funes","preferred_username":"victor.funes@mymail.com","email":"victor.funes@mymail.com","email_verified":true,"acr":"1","realm_access":{"roles":["offline_access","Client_User_Role","default-roles-client","uma_authorization"]},"resource_access":{"account":{"roles":["manage-account","manage-account-links","view-profile"]}},"scope":"email profile","sid":"77b60fd0-cbfb-4643-9a33-3dc7393bce15","client_id":"Client","username":"victor.funes@mymail.com","active":true}

The problem is just after this step of introspection when after the authorization kong has to call to the original endpoint:

2022/10/20 11:53:05 [debug] 1378#0: *865 [lua] handler.lua:141: introspect(): OidcHandler introspect succeeded, requested path: /mock/requests
2022/10/20 11:53:05 [error] 1378#0: *865 [kong] init.lua:290 [oidc] /usr/local/share/lua/5.1/kong/plugins/oidc/utils.lua:122: header must be a string, client: 172.19.0.1, server: kong, request: "GET /mock/requests HTTP/1.1", host: "localhost:8000"
172.19.0.1 - - [20/Oct/2022:11:53:05 +0000] "GET /mock/requests HTTP/1.1" 500 42 "-" "PostmanRuntime/7.29.2"

I use mockbin.org for testing, and I have tested the service and the route in kong before adding OIDC, working properly.
After adding the OIDC plugin and configure it, I get this error.

@victorfunes victorfunes reopened this Oct 20, 2022
@ruiengana
Copy link
Collaborator

ruiengana commented Oct 20, 2022 via email

@victorfunes
Copy link
Author

I start the environment with docker-compose, and I already have in the environment this level of log you are requesting (KONG_LOG_LEVEL=debug) as you can see in the extract of my yaml (unless I did something wrong like a typo):

kong:
image: revomatico/docker-kong-oidc:latest
container_name: kong
restart: always
user: kong
depends_on:
- postgres-kong
- kong-migrations
- kong-migrations-up
environment:
- KONG_LOG_LEVEL=debug
- KONG_ADMIN_ACCESS_LOG=/dev/stdout
- KONG_ADMIN_ERROR_LOG=/dev/stderr
- KONG_ADMIN_GUI_ACCESS_LOG=/dev/stdout
- KONG_ADMIN_GUI_ERROR_LOG=/dev/stderr
- KONG_PORTAL_API_ACCESS_LOG=/dev/stdout
- KONG_PORTAL_API_ERROR_LOG=/dev/stderr
- KONG_PROXY_ACCESS_LOG=/dev/stdout
- KONG_PROXY_ERROR_LOG=/dev/stderr
- KONG_ANONYMOUS_REPORTS=false
- KONG_CLUSTER_LISTEN=off
- "KONG_LUA_PACKAGE_PATH=/opt/?.lua;/opt/?/init.lua;;"
- KONG_NGINX_WORKER_PROCESSES=1
- "KONG_PLUGINS=bundled,oidc"
- "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl"
- "KONG_PROXY_LISTEN=0.0.0.0:8000, 0.0.0.0:8443 http2 ssl"
- "KONG_STATUS_LISTEN=0.0.0.0:8100"
- KONG_NGINX_DAEMON=off
- "KONG_X_SESSION_MEMCACHE_PORT='1234'"
- KONG_X_SESSION_COMPRESSOR=zlib
- KONG_DATABASE=postgres
- KONG_PG_DATABASE=kong
- KONG_PG_HOST=postgres-kong
- KONG_PG_PORT=5432
- KONG_PG_USER=kong
- KONG_PG_PASSWORD=kongpassword
links:
- postgres-kong
networks:
- kong-network
ports:
- "8000:8000/tcp"
- "127.0.0.1:8001:8001/tcp"
- "8443:8443/tcp"
- "127.0.0.1:8444:8444/tcp"
healthcheck:
test: ["CMD", "kong", "health"]
interval: 10s
timeout: 10s
retries: 10

I also show you the service and the route configuration done in kong.
As I said, it works if I delete the OIDC plugin and try to access.

SERVICE:
{
"updated_at": 1666266370,
"host": "mockbin.org",
"path": null,
"enabled": true,
"id": "93cea7e5-35ab-406b-a016-584b2ebd821b",
"retries": 5,
"write_timeout": 60000,
"tags": [],
"ca_certificates": null,
"port": 8080,
"tls_verify": null,
"client_certificate": null,
"tls_verify_depth": null,
"protocol": "http",
"name": "MockbinService",
"read_timeout": 60000,
"connect_timeout": 60000,
"created_at": 1666265649,
"extras": {
"createdUser": null,
"updatedUser": null,
"kong_node_id": "1",
"service_id": "93cea7e5-35ab-406b-a016-584b2ebd821b",
"createdAt": "2022-10-20T11:34:09.137Z",
"updatedAt": "2022-10-20T11:46:10.368Z",
"id": 1
}
}

ROUTE:
{
"updated_at": 1666266410,
"headers": null,
"path_handling": "v1",
"id": "80ee30b0-4691-4ceb-943c-9cc203d7ffb2",
"snis": null,
"strip_path": true,
"tags": null,
"hosts": null,
"service": {
"id": "93cea7e5-35ab-406b-a016-584b2ebd821b"
},
"destinations": null,
"paths": [
"/mock"
],
"methods": null,
"request_buffering": true,
"response_buffering": true,
"sources": null,
"name": "MockbinRoute",
"https_redirect_status_code": 426,
"protocols": [
"http",
"https"
],
"preserve_host": false,
"regex_priority": 0,
"created_at": 1666265686
}

@ruiengana
Copy link
Collaborator

ruiengana commented Oct 21, 2022 via email

@victorfunes
Copy link
Author

I hope this helps.
Something I realized taking these logs: if I disable OIDC plugin it keeps failing with the same error, I need to delete it to avoid failure. It is a really strange behaviour...

--------- Logs for the call with OIDC driver configured ------------
INTROSPECT SUCCESS: 2022/10/21 09:35:40
ERROR: 2022/10/21 09:35:40

2022/10/21 09:35:37 [debug] 1389#0: *185 [lua] init.lua:288: [cluster_events] polling events from: 1666343729.975
2022/10/21 09:35:39 [info] 1389#0: *189 client closed connection while waiting for request, client: 172.19.0.1, server: 0.0.0.0:8000
2022/10/21 09:35:39 [debug] 1389#0: *188 [lua] openidc.lua:515: call_token_endpoint(): request body for introspection endpoint call: token=eyJ...6Tw&client_secret=DYC...p8u&client_id=Client
2022/10/21 09:35:39 [debug] 1389#0: *188 [lua] openidc.lua:434: openidc_configure_proxy(): openidc_configure_proxy : don't use http proxy
2022/10/21 09:35:40 [debug] 1389#0: *188 [lua] openidc.lua:533: call_token_endpoint(): introspection endpoint response: {"exp":1666345212,"iat":1666344912,"jti":"d4d8e6bc-ee84-41e8-bb46-1d74fab3b351","iss":"http://keycloak:8080/auth/realms/MyRealm","aud":"account","sub":"e5f73956-9753-4ade-aad1-115b34567fed","typ":"Bearer","azp":"Client","session_state":"6d4b8a2b-ed63-43cb-875f-d32c10f17341","name":"Victor Funes","given_name":"Victor","family_name":"Funes","preferred_username":"victor.funes@mymail.com","email":"victor.funes@mymail.com","email_verified":true,"acr":"1","realm_access":{"roles":["offline_access","Client_User_Role","default-roles-client","uma_authorization"]},"resource_access":{"account":{"roles":["manage-account","manage-account-links","view-profile"]}},"scope":"email profile","sid":"6d4b8a2b-ed63-43cb-875f-d32c10f17341","client_id":"Client","username":"victor.funes@mymail.com","active":true}
2022/10/21 09:35:40 [debug] 1389#0: *188 [lua] handler.lua:141: introspect(): OidcHandler introspect succeeded, requested path: /mock/requests
2022/10/21 09:35:40 [error] 1389#0: *188 [kong] init.lua:290 [oidc] /usr/local/share/lua/5.1/kong/plugins/oidc/utils.lua:122: header must be a string, client: 172.19.0.1, server: kong, request: "GET /mock/requests HTTP/1.1", host: "localhost:8000"
172.19.0.1 - - [21/Oct/2022:09:35:40 +0000] "GET /mock/requests HTTP/1.1" 500 42 "-" "PostmanRuntime/7.29.2"
2022/10/21 09:35:42 [debug] 1389#0: *177 [lua] init.lua:288: [cluster_events] polling events from: 1666343729.975
2022/10/21 09:35:47 [debug] 1389#0: *157 [lua] init.lua:288: [cluster_events] polling events from: 1666343729.975
2022/10/21 09:35:52 [debug] 1389#0: *173 [lua] init.lua:288: [cluster_events] polling events from: 1666343729.975

-------------- Logs for the call without OIDC driver configured (including plugin deletion) -------------

SUCCESS CALL: 2022/10/21 09:45:37

2022/10/21 09:44:47 [debug] 1389#0: *3 [lua] callback.lua:114: do_event(): worker-events: handling event; source=dao:crud, event=delete, wid=nil
2022/10/21 09:44:47 [debug] 1389#0: *3 [lua] init.lua:214: invalidate_local(): [DB cache] invalidating (local): 'plugins:oidc:::::91fa34c5-8276-4056-b049-533f47e9cbc1'
2022/10/21 09:44:47 [debug] 1389#0: *3 [lua] init.lua:230: invalidate(): [DB cache] broadcasting (cluster) invalidation for key: 'plugins:oidc:::::91fa34c5-8276-4056-b049-533f47e9cbc1'
2022/10/21 09:44:47 [debug] 1389#0: *149 [lua] broker.lua:73: broadcast_events(): event published to 1 workers
2022/10/21 09:44:47 [debug] 1389#0: *232 [lua] init.lua:23: poll(): worker-events: emulate poll method
2022/10/21 09:44:47 [debug] 1389#0: *3 [lua] callback.lua:114: do_event(): worker-events: handling event; source=mlcache, event=mlcache:invalidations:kong_core_db_cache, wid=0
2022/10/21 09:44:47 [debug] 1389#0: *3 [lua] callback.lua:114: do_event(): worker-events: handling event; source=crud, event=plugins, wid=nil
2022/10/21 09:44:47 [debug] 1389#0: *3 [lua] handler.lua:506: [events] Plugin updated, invalidating plugins iterator
2022/10/21 09:44:47 [debug] 1389#0: *3 [lua] init.lua:214: invalidate_local(): [DB cache] invalidating (local): 'plugins_iterator:version'
2022/10/21 09:44:47 [debug] 1389#0: *3 [lua] init.lua:230: invalidate(): [DB cache] broadcasting (cluster) invalidation for key: 'plugins_iterator:version'
172.19.0.7 - kong [21/Oct/2022:09:44:47 +0000] "DELETE /plugins/7847568c-1ca2-486b-9222-2b3fd4c19574 HTTP/1.1" 204 0 "-" "-"
2022/10/21 09:44:47 [debug] 1389#0: *149 [lua] broker.lua:73: broadcast_events(): event published to 1 workers
2022/10/21 09:44:47 [debug] 1389#0: *3 [lua] callback.lua:114: do_event(): worker-events: handling event; source=crud, event=plugins:delete, wid=nil
2022/10/21 09:44:47 [debug] 1389#0: *3 [lua] callback.lua:114: do_event(): worker-events: handling event; source=mlcache, event=mlcache:invalidations:kong_core_db_cache, wid=0
2022/10/21 09:44:52 [debug] 1389#0: *221 [lua] init.lua:288: [cluster_events] polling events from: 1666343729.975
2022/10/21 09:44:57 [debug] 1389#0: *200 [lua] init.lua:288: [cluster_events] polling events from: 1666345492.233
2022/10/21 09:45:02 [debug] 1389#0: *210 [lua] init.lua:288: [cluster_events] polling events from: 1666345492.233
2022/10/21 09:45:07 [debug] 1389#0: *196 [lua] init.lua:288: [cluster_events] polling events from: 1666345492.233
2022/10/21 09:45:11 [debug] 1389#0: *230 [lua] init.lua:1077: balancer(): setting address (try 1): 172.67.178.52:8080
2022/10/21 09:45:11 [debug] 1389#0: *230 [lua] init.lua:1106: balancer(): enabled connection keepalive (pool=172.67.178.52|8080, pool_size=60, idle_timeout=60, max_requests=100)
2022/10/21 09:45:12 [debug] 1389#0: *194 [lua] init.lua:288: [cluster_events] polling events from: 1666345492.233
2022/10/21 09:45:17 [debug] 1389#0: *221 [lua] init.lua:288: [cluster_events] polling events from: 1666345492.233
2022/10/21 09:45:22 [debug] 1389#0: *205 [lua] init.lua:288: [cluster_events] polling events from: 1666345492.233
2022/10/21 09:45:27 [debug] 1389#0: *215 [lua] init.lua:288: [cluster_events] polling events from: 1666345492.233
2022/10/21 09:45:35 [info] 1389#0: *2 [lua] super.lua:161: scaling_log(): [timer-ng] load_avg: 0.07489224137931, runable_jobs_avg: 2.3965517241379, alive_threads_avg: 32, context: ngx.timer
2022/10/21 09:45:37 [debug] 1389#0: *206 [lua] init.lua:288: [cluster_events] polling events from: 1666345492.233
172.19.0.1 - - [21/Oct/2022:09:45:42 +0000] "GET /mock/requests HTTP/1.1" 522 7152 "-" "PostmanRuntime/7.29.2"
2022/10/21 09:45:47 [debug] 1389#0: *199 [lua] init.lua:288: [cluster_events] polling events from: 1666345492.233
2022/10/21 09:45:52 [debug] 1389#0: *206 [lua] init.lua:288: [cluster_events] polling events from: 1666345492.233
2022/10/21 09:45:57 [debug] 1389#0: *221 [lua] init.lua:288: [cluster_events] polling events from: 1666345492.233

@ruiengana
Copy link
Collaborator

ruiengana commented Oct 21, 2022

According to log the error 2022/10/21 09:35:40 [error] 1389#0: *188 [kong] init.lua:290 [oidc] /usr/local/share/lua/5.1/kong/plugins/oidc/utils.lua:122: header must be a string, client: 172.19.0.1, server: kong, request: "GET /mock/requests HTTP/1.1", host: "localhost:8000" seems to be the culprit of it.

  if credential and credential.username then
    set_header(constants.HEADERS.CREDENTIAL_IDENTIFIER, credential.username)
  else
    clear_header(constants.HEADERS.CREDENTIAL_IDENTIFIER)
  end

It seems that constants.HEADERS.CREDENTIAL_IDENTIFIER is not defined...

@ruiengana
Copy link
Collaborator

@christichiru, can't find a way to bring you to the conversation, only found the assign button (sorry about that) :P

@victorfunes
Copy link
Author

I saw this error and the source code, and looking in the original file of kong (https://github.com/Kong/kong/blob/master/kong/constants.lua) it is indeed defined:

CREDENTIAL_IDENTIFIER = "X-Credential-Identifier"

So my assumption was I was doing something wrong from the configuration point of view.

I did not install kong by myself, but as you can see in my docker-compose, the image I am using is:
revomatico/docker-kong-oidc:latest

@cristichiru
Copy link

cristichiru commented Oct 21, 2022

The weird part is that the constant is defined, as expected. The issue has a different cause root cause, but the message is misleading. Those constants are used exactly like in many other plugins (the onses bundled with kong).

AjO8m76MrZ

This is from the latest docker-kong-oidc image.

@victorfunes can you please use image tag 3.0.0-6 instead of latest?

@victorfunes
Copy link
Author

Hi,
Now the situation changes: introspection is failing because Realm is not found in Keycloak (but I checked the Realm several times and exists), and if I use the token and execute from Postman manually introspection, it works without issues.

The logs are:

2022/10/21 14:17:27 [debug] 1379#0: *427 [lua] init.lua:288: [cluster_events] polling events from: 1666361782.812
2022/10/21 14:17:30 [info] 1379#0: *455 client closed connection while waiting for request, client: 172.19.0.1, server: 0.0.0.0:8000
2022/10/21 14:17:30 [debug] 1379#0: *456 [lua] openidc.lua:515: call_token_endpoint(): request body for introspection endpoint call: token=eyJ...p8u
2022/10/21 14:17:30 [debug] 1379#0: *456 [lua] openidc.lua:434: openidc_configure_proxy(): openidc_configure_proxy : don't use http proxy
2022/10/21 14:17:30 [debug] 1379#0: *456 [lua] openidc.lua:533: call_token_endpoint(): introspection endpoint response: {"error":"Realm does not exist"}
172.19.0.1 - - [21/Oct/2022:14:17:30 +0000] "GET /mock/requests HTTP/1.1" 401 30 "-" "PostmanRuntime/7.29.2"

@victorfunes
Copy link
Author

victorfunes commented Oct 21, 2022

Additional info: the test I do with introspection is using the auth token given directly by Keycloak.
I tested with the token in the logs of kong and introspection also works from Postman (initially I got an error because a the end it had concatenated the &client_id=Client&client_secret=XXXXXXXXX, and I did not realize).

@victorfunes
Copy link
Author

Please, let me know if I can help providing any other information.
The issue still persists.
Thank you!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants