directus icon indicating copy to clipboard operation
directus copied to clipboard

SSO: Keycloak refresh token not working

Open jofmi opened this issue 1 year ago • 2 comments
trafficstars

Describe the Bug

We use Directus Seamless SSO with Keycloak in "session" mode. Authentication works great, auth/refresh works as well.

However, Directus is not able to use the Keycloak refresh token after the Keycloak session expires. You can see in the logs that it first tries to use the session token and then tries to use the refresh token.

2024-04-22 11:05:39 [09:05:39] POST /auth/refresh 403 15ms
2024-04-22 11:05:39 [09:05:39.463] WARN: [OpenID] Invalid grant
2024-04-22 11:05:39     err: {
2024-04-22 11:05:39       "type": "OPError",
2024-04-22 11:05:39       "message": "invalid_grant (Token is not active)",
2024-04-22 11:05:39       "stack":
2024-04-22 11:05:39           OPError: invalid_grant (Token is not active)
2024-04-22 11:05:39               at processResponse (/directus/node_modules/.pnpm/[email protected]/node_modules/openid-client/lib/helpers/process_response.js:38:13)
2024-04-22 11:05:39               at Client.grant (/directus/node_modules/.pnpm/[email protected]/node_modules/openid-client/lib/client.js:1354:22)
2024-04-22 11:05:39               at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
2024-04-22 11:05:39               at async Client.refresh (/directus/node_modules/.pnpm/[email protected]/node_modules/openid-client/lib/client.js:1098:22)
2024-04-22 11:05:39               at async OpenIDAuthDriver.refresh (file:///directus/node_modules/.pnpm/file+api_@[email protected][email protected][email protected][email protected]/node_modules/@directus/api/dist/auth/drivers/openid.js:200:34)
2024-04-22 11:05:39               at async AuthenticationService.refresh (file:///directus/node_modules/.pnpm/file+api_@[email protected][email protected][email protected][email protected]/node_modules/@directus/api/dist/services/authentication.js:261:13)
2024-04-22 11:05:39               at async file:///directus/node_modules/.pnpm/file+api_@[email protected][email protected][email protected][email protected]/node_modules/@directus/api/dist/controllers/auth.js:94:52
2024-04-22 11:05:39       "error": "invalid_grant",
2024-04-22 11:05:39       "error_description": "Token is not active",
2024-04-22 11:05:39       "name": "OPError"
2024-04-22 11:05:39     }
2024-04-22 11:05:39 [09:05:39.463] DEBUG: Invalid token.
2024-04-22 11:05:39     err: {
2024-04-22 11:05:39       "type": "",
2024-04-22 11:05:39       "message": "Invalid token.",
2024-04-22 11:05:39       "stack":
2024-04-22 11:05:39           DirectusError: Invalid token.
2024-04-22 11:05:39               at handleError (file:///directus/node_modules/.pnpm/file+api_@[email protected][email protected][email protected][email protected]/node_modules/@directus/api/dist/auth/drivers/openid.js:220:20)
2024-04-22 11:05:39               at OpenIDAuthDriver.refresh (file:///directus/node_modules/.pnpm/file+api_@[email protected][email protected][email protected][email protected]/node_modules/@directus/api/dist/auth/drivers/openid.js:209:23)
2024-04-22 11:05:39               at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
2024-04-22 11:05:39               at async AuthenticationService.refresh (file:///directus/node_modules/.pnpm/file+api_@[email protected][email protected][email protected][email protected]/node_modules/@directus/api/dist/services/authentication.js:261:13)
2024-04-22 11:05:39               at async file:///directus/node_modules/.pnpm/file+api_@[email protected][email protected][email protected][email protected]/node_modules/@directus/api/dist/controllers/auth.js:94:52
2024-04-22 11:05:39       "name": "DirectusError",
2024-04-22 11:05:39       "code": "INVALID_TOKEN",
2024-04-22 11:05:39       "status": 403
2024-04-22 11:05:39     }

On Keycloak's side:

2024-04-22 11:05:39 2024-04-22 09:05:39,462 WARN  [org.keycloak.events] (executor-thread-20) type="REFRESH_TOKEN_ERROR", realmId="<MYID>", clientId="directus", userId="null", ipAddress="<MYIP>", error="invalid_token", grant_type="refresh_token", client_auth_method="client-secret"

This affects the user refresh token as well as the client refresh token (the latter logging out all users once it expired).

To Reproduce

I use the Directus Docker Image v10.10.7 with the following env vars for authentication:

AUTH_PROVIDERS: "keycloak"
AUTH_KEYCLOAK_MODE: "session"
AUTH_KEYCLOAK_DRIVER: "openid"
AUTH_KEYCLOAK_CLIENT_ID: ${KEYCLOAK_DIRECTUS_CLIENT}
AUTH_KEYCLOAK_CLIENT_SECRET: ${KEYCLOAK_DIRECTUS_SECRET}
AUTH_KEYCLOAK_ISSUER_URL: "${KEYCLOAK_URL}/realms/collectivo/.well-known/openid-configuration"
AUTH_KEYCLOAK_IDENTIFIER_KEY: "email"
AUTH_KEYCLOAK_ALLOW_PUBLIC_REGISTRATION: "true"

And Keycloak 23.0. (quay.io/keycloak/keycloak:23.0) with the following OIDC settings:

grafik

To reproduce the error, log in to the data studio and wait until the Keycloak session expires, then refresh the page.

The Keycloak session expiration time can be set in the Keycloak Admin console under realm settings -> sessions -> SSO session idle.

Directus Version

v10.10.7

Hosting Strategy

Self-Hosted (Docker Image)

jofmi avatar Apr 22 '24 09:04 jofmi

Maybe helpful. I see in my storage that there are two cookies:

  • directus_session_token, which has a value
  • directus_refresh_token, which is empty

Could it be that the Keycloak refresh token is not stored at all?

Also, when I switch the "AUTH_KEYCLOAK_MODE" back to "cookie", the "Login with Keycloak" Button in Directus Studio disappears.

jofmi avatar May 23 '24 11:05 jofmi

Maybe helpful. I see in my storage that there are two cookies:

* directus_session_token, which has a value

* directus_refresh_token, which is empty

Could it be that the Keycloak refresh token is not stored at all?

directus_refresh_token is not applicable here, directus_session_token is your "session token" which covers both access and refresh.

Also, when I switch the "AUTH_KEYCLOAK_MODE" back to "cookie", the "Login with Keycloak" Button in Directus Studio disappears.

That is by design since you cannot use cookie mode to log into the app.

br41nslug avatar May 23 '24 11:05 br41nslug

facing the same, directus version 10.12

useEffects avatar Sep 05 '24 19:09 useEffects