git.iko.soy/typeable/oauth2-proxy
on master help sign in
fix: session refresh handling in OIDC provider (#3267)

* Fix session refresh handling in OIDC provider - `s.Refreshed` was always `false` as the session object was not updated - `ValidateURL` is, by default, not configured for OIDC providers. Access token validation now only happens when a validation endpoint is available. Signed-off-by: Michael Gysel <michael.gysel@unblu.com> * Update changelog Signed-off-by: Michael Gysel <michael.gysel@unblu.com> --------- Signed-off-by: Michael Gysel <michael.gysel@unblu.com>

commit49536035a2ae26adb2d663ba2fa1d80257cb3ca8 authorMichi Gysel <michael.gysel@unblu.com> dateWed 14 Jan 2026, 23:18 (9 months ago) parentb4eb611
2 files changed+6−7
CHANGELOG.md+1 providers/oidc.go+5−7
CHANGELOG.md+1
@@ -12,6 +12,7 @@
1212- [#3292](https://github.com/oauth2-proxy/oauth2-proxy/pull/3292) chore(deps): upgrade gomod and bump to golang v1.25.5 (@tuunit)
1313- [#3304](https://github.com/oauth2-proxy/oauth2-proxy/pull/3304) fix: added conditional so default is not always set and env vars are honored fixes 3303 (@pixeldrew)
1414- [#3264](https://github.com/oauth2-proxy/oauth2-proxy/pull/3264) fix: more aggressively truncate logged access_token (@MartinNowak / @tuunit)
15+- [#3267](https://github.com/oauth2-proxy/oauth2-proxy/pull/3267) fix: Session refresh handling in OIDC provider (@gysel)
1516
1617# V7.13.0
1718
providers/oidc.go+5−7
@@ -117,14 +117,12 @@ func (p *OIDCProvider) ValidateSession(ctx context.Context, s *sessions.SessionS
117117
118118 // https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokenResponse
119119 // The ID Token is optional in the Refresh Token Response
120− // TODO: @tuunit remove dependency on refreshed flag and only rely on presence of access_token
121− // in accordance with the spec. For now, keep existing behavior.
122120 if s.Refreshed {
123− if !validateToken(ctx, p, s.AccessToken, makeOIDCHeader(s.AccessToken)) {
121+ validateEndpointAvailable := p.Data().ValidateURL != nil && p.Data().ValidateURL.String() != ""
122+ if validateEndpointAvailable && !validateToken(ctx, p, s.AccessToken, makeOIDCHeader(s.AccessToken)) {
124123 logger.Errorf("access_token validation failed")
125124 return false
126125 }
127−
128126 return true
129127 }
130128
@@ -190,9 +188,8 @@ func (p *OIDCProvider) redeemRefreshToken(ctx context.Context, s *sessions.Sessi
190188 return fmt.Errorf("unable create new session state from response: %v", err)
191189 }
192190
193− // It's possible that if the refresh token isn't in the token response the
194− // session will not contain an id token.
195− // If it doesn't it's probably better to retain the old one
191+ // It's possible that a refresh does not renew the ID Token.
192+ // If it doesn't, it's probably better to retain the old one.
196193 if newSession.IDToken != "" {
197194 s.IDToken = newSession.IDToken
198195 s.Email = newSession.Email
@@ -205,6 +202,7 @@ func (p *OIDCProvider) redeemRefreshToken(ctx context.Context, s *sessions.Sessi
205202 s.RefreshToken = newSession.RefreshToken
206203 s.CreatedAt = newSession.CreatedAt
207204 s.ExpiresOn = newSession.ExpiresOn
205+ s.Refreshed = newSession.Refreshed
208206
209207 return nil
210208}