From f03d4fe821a87f9f2e27046664a234381a5656f6 Mon Sep 17 00:00:00 2001 From: Martin Linkhorst Date: Fri, 17 Feb 2023 07:25:11 +0100 Subject: [PATCH] get-token: add --force-refresh flag to refresh ID token (#879) --- pkg/cmd/get_token.go | 3 ++ pkg/usecases/authentication/authentication.go | 35 +++++++++++-------- pkg/usecases/credentialplugin/get_token.go | 2 ++ 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/pkg/cmd/get_token.go b/pkg/cmd/get_token.go index 043efe13..bff4bc07 100644 --- a/pkg/cmd/get_token.go +++ b/pkg/cmd/get_token.go @@ -21,6 +21,7 @@ type getTokenOptions struct { TokenCacheDir string tlsOptions tlsOptions authenticationOptions authenticationOptions + ForceRefresh bool } func (o *getTokenOptions) addFlags(f *pflag.FlagSet) { @@ -30,6 +31,7 @@ func (o *getTokenOptions) addFlags(f *pflag.FlagSet) { f.StringSliceVar(&o.ExtraScopes, "oidc-extra-scope", nil, "Scopes to request to the provider") f.BoolVar(&o.UsePKCE, "oidc-use-pkce", false, "Force PKCE usage") f.StringVar(&o.TokenCacheDir, "token-cache-dir", defaultTokenCacheDir, "Path to a directory for token cache") + f.BoolVar(&o.ForceRefresh, "force-refresh", false, "If set, refresh the ID token regardless of its expiration time") o.tlsOptions.addFlags(f) o.authenticationOptions.addFlags(f) } @@ -82,6 +84,7 @@ func (cmd *GetToken) New() *cobra.Command { TokenCacheDir: o.TokenCacheDir, GrantOptionSet: grantOptionSet, TLSClientConfig: o.tlsOptions.tlsClientConfig(), + ForceRefresh: o.ForceRefresh, } if err := cmd.GetToken.Do(c.Context(), in); err != nil { return fmt.Errorf("get-token: %w", err) diff --git a/pkg/usecases/authentication/authentication.go b/pkg/usecases/authentication/authentication.go index 61cf2bf0..5fa44b72 100644 --- a/pkg/usecases/authentication/authentication.go +++ b/pkg/usecases/authentication/authentication.go @@ -35,6 +35,7 @@ type Input struct { GrantOptionSet GrantOptionSet CachedTokenSet *oidc.TokenSet // optional TLSClientConfig tlsclientconfig.Config + ForceRefresh bool } type GrantOptionSet struct { @@ -74,22 +75,26 @@ type Authentication struct { func (u *Authentication) Do(ctx context.Context, in Input) (*Output, error) { if in.CachedTokenSet != nil { - u.Logger.V(1).Infof("checking expiration of the existing token") - // Skip verification of the token to reduce time of a discovery request. - // Here it trusts the signature and claims and checks only expiration, - // because the token has been verified before caching. - claims, err := in.CachedTokenSet.DecodeWithoutVerify() - if err != nil { - return nil, fmt.Errorf("invalid token cache (you may need to remove): %w", err) - } - if !claims.IsExpired(u.Clock) { - u.Logger.V(1).Infof("you already have a valid token until %s", claims.Expiry) - return &Output{ - AlreadyHasValidIDToken: true, - TokenSet: *in.CachedTokenSet, - }, nil + if in.ForceRefresh { + u.Logger.V(1).Infof("forcing refresh of the existing token") + } else { + u.Logger.V(1).Infof("checking expiration of the existing token") + // Skip verification of the token to reduce time of a discovery request. + // Here it trusts the signature and claims and checks only expiration, + // because the token has been verified before caching. + claims, err := in.CachedTokenSet.DecodeWithoutVerify() + if err != nil { + return nil, fmt.Errorf("invalid token cache (you may need to remove): %w", err) + } + if !claims.IsExpired(u.Clock) { + u.Logger.V(1).Infof("you already have a valid token until %s", claims.Expiry) + return &Output{ + AlreadyHasValidIDToken: true, + TokenSet: *in.CachedTokenSet, + }, nil + } + u.Logger.V(1).Infof("you have an expired token at %s", claims.Expiry) } - u.Logger.V(1).Infof("you have an expired token at %s", claims.Expiry) } u.Logger.V(1).Infof("initializing an OpenID Connect client") diff --git a/pkg/usecases/credentialplugin/get_token.go b/pkg/usecases/credentialplugin/get_token.go index 77738d67..7db246db 100644 --- a/pkg/usecases/credentialplugin/get_token.go +++ b/pkg/usecases/credentialplugin/get_token.go @@ -37,6 +37,7 @@ type Input struct { TokenCacheDir string GrantOptionSet authentication.GrantOptionSet TLSClientConfig tlsclientconfig.Config + ForceRefresh bool } type GetToken struct { @@ -90,6 +91,7 @@ func (u *GetToken) Do(ctx context.Context, in Input) error { GrantOptionSet: in.GrantOptionSet, CachedTokenSet: cachedTokenSet, TLSClientConfig: in.TLSClientConfig, + ForceRefresh: in.ForceRefresh, } authenticationOutput, err := u.Authentication.Do(ctx, authenticationInput) if err != nil {