keycloak/keycloak

GET /broker/{alias}/token returns expired external IDP access token when refresh_token is available

Open

#49 341 ouverte le 26 mai 2026

Voir sur GitHub
 (2 commentaires) (1 réaction) (0 assignés)Java (8 346 forks)batch import
area/identity-brokeringhelp wantedkind/bugpriority/normalstatus/auto-bumpstatus/auto-expireteam/core-iam

Métriques du dépôt

Stars
 (34 398 stars)
Métriques de merge PR
 (Merge moyen 6j 19h) (384 PRs mergées en 30 j)

Description

Summary

`GET /realms/{realm}/broker/{provider_alias}/token` (both V1 and V2 APIs) should automatically refresh the stored external IDP access token when it has expired and a refresh_token is available.

Steps to Reproduce

  1. Configure an OAuth2/OIDC external IDP with `Store Tokens` enabled
  2. Log in via the external IDP
  3. Wait for the external IDP access token to expire
  4. Call `GET /realms/{realm}/broker/{alias}/token`

Expected Behavior

The endpoint should automatically use the stored refresh_token to obtain a fresh access token, persist it, and return the new token.

Actual Behavior

The expired access token is returned without attempting a refresh. In some cases this causes a 401 error when the caller uses the token.

Root Cause

The `exchangeStoredToken` method in `AbstractOAuth2IdentityProvider` retrieves the stored token but does not check expiration or attempt refresh before returning.

Note: The V1 `retrieveToken(session, identity)` was fixed in #39508, but `exchangeStoredToken` (called by V2 and token exchange) was not updated.

Environment

  • Keycloak (latest main)
  • Any OAuth2/OIDC external IDP (GitHub, Google, etc.)

Guide contributeur