identity: override TokenSource expiry behavior (#4632)

The current session refresh loop attempts to refresh access tokens when
they are due to expire in less than one minute. However, the code to
perform the refresh relies on a TokenSource from the x/oauth2 package,
which has its own internal 'expiryDelta' threshold, with a default of
10 seconds. As a result, the first four or five attempts to refresh a
particular access token will not actually refresh the token. The refresh
will happen only when the access token is within 10 seconds of expiring.

Instead, before we obtain a new TokenSource, first clear any existing
access token. This causes the TokenSource to consider the token invalid,
triggering a refresh. This should give the refresh loop more control
over when refreshes happen.

Consolidate this logic in a new Refresh() method in the oidc package.
Add unit tests for this new method.
This commit is contained in:
Kenneth Jenkins 2023-10-23 08:20:04 -07:00 committed by GitHub
parent 5a735264b3
commit 39a477c510
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 104 additions and 18 deletions

View file

@ -213,16 +213,9 @@ func (p *Provider) Refresh(ctx context.Context, t *oauth2.Token, v identity.Stat
return nil, err
}
if t == nil {
return nil, ErrMissingAccessToken
}
if t.RefreshToken == "" {
return nil, ErrMissingRefreshToken
}
newToken, err := oa.TokenSource(ctx, t).Token()
newToken, err := Refresh(ctx, oa, t)
if err != nil {
return nil, fmt.Errorf("identity/oidc: refresh failed: %w", err)
return nil, err
}
// Many identity providers _will not_ return `id_token` on refresh