OIDC Refresh Token Implementation#
The OIDC provider's refresh token flow is intentionally minimal: it delegates entirely to the standard golang.org/x/oauth2 library to exchange the stored refresh token for new tokens, adding no provider-specific parameters. This contrasts with providers like Google and Azure, which construct manual HTTP POST requests with explicit client_id, client_secret, and grant_type fields.
Entry Point#
RefreshSession is the public interface method (satisfying Provider.RefreshSession). It guards against nil or empty-RefreshToken sessions, then delegates to the unexported redeemRefreshToken.
Core Redemption: redeemRefreshToken#
redeemRefreshToken does the following:
-
Builds an
oauth2.Configusing onlyClientID,ClientSecret, and theRedeemURLtoken endpoint β no scopes, redirect URL, or extra parameters are added . -
Constructs a pre-expired
oauth2.Tokenwith the session'sRefreshTokenset andExpiryforced into the past (time.Now().Add(-time.Hour)). This ensures the oauth2 library'sTokenSourcealways treats the token as expired and performs a refresh . -
Calls
c.TokenSource(ctx, t).Token()β the standard oauth2 library handles the token endpoint request, including encodinggrant_type=refresh_tokenand client credentials . -
Creates a new session via
createSession(ctx, token, true), passingrefresh=trueto signal that a missing ID token is acceptable . -
Selectively updates the existing session β claim fields (
IDToken,Email,User,Groups,PreferredUsername) are only overwritten when a new ID token is present;AccessToken,RefreshToken,CreatedAt,ExpiresOn, andRefreshedare always updated .
Why the ID Token is Optional on Refresh#
Per OIDC Core Β§12, the ID token is optional in a refresh token response. The code explicitly handles this case at createSession: if ErrMissingIDToken occurs and refresh=true, it proceeds without one. Consequently, the existing session's identity claims are preserved .
The ValidateSession method also accounts for this: when s.Refreshed is true, it skips ID token verification and instead optionally validates the access token against the ValidateURL .
Comparison with Other Providers#
| Provider | Refresh Approach | Provider-Specific Params |
|---|---|---|
| OIDC | oauth2.TokenSource (standard lib) | None |
| Manual HTTP POST | client_id, client_secret, grant_type | |
| Azure | Manual HTTP POST | client_id, client_secret, grant_type |
| MS Entra ID (federated) | Manual HTTP POST | client_assertion, client_assertion_type, expiry |
| CIDAAS | Inherits OIDC | None (post-refresh EnrichSession) |
Providers built on top of OIDCProvider (CIDAAS, KeycloakOIDC, ADFS) reuse this implementation rather than reimplementing refresh logic.
Key Files#
| File | Role |
|---|---|
providers/oidc.go | RefreshSession, redeemRefreshToken, createSession |
providers/provider_data.go | verifyIDToken, buildSessionFromClaims, ProviderData struct |
providers/util.go | getIDToken β extracts id_token from oauth2.Token.Extra |
providers/providers.go | Provider interface β RefreshSession contract |