keycloak/keycloak

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

Open

#49,341 opened on 2026年5月26日

GitHub で見る
 (2 comments) (1 reaction) (0 assignees)Java (8,346 forks)batch import
area/identity-brokeringhelp wantedkind/bugpriority/normalstatus/auto-bumpstatus/auto-expireteam/core-iam

Repository metrics

Stars
 (34,398 stars)
PR merge metrics
 (平均マージ 6d 19h) (30d で 384 merged PRs)

説明

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.)

コントリビューターガイド