From 284fa2a76f586aab223123bd4b228ca9589ce37d Mon Sep 17 00:00:00 2001 From: Trong Huu Nguyen Date: Mon, 18 Jul 2022 09:24:20 +0200 Subject: [PATCH] fix(openid/client): ensure assertion time claims are rounded down instead of up Hopefully fixes intermittent 'invalid_grant' errors from IdP. --- pkg/jwt/jwt.go | 2 +- pkg/mock/openid.go | 10 ++++++---- pkg/openid/client/client.go | 2 +- pkg/openid/tokens.go | 2 +- pkg/session/session_id_test.go | 6 ++++-- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/pkg/jwt/jwt.go b/pkg/jwt/jwt.go index 8a8188f..a9794a5 100644 --- a/pkg/jwt/jwt.go +++ b/pkg/jwt/jwt.go @@ -10,7 +10,7 @@ import ( ) const ( - AcceptableClockSkew = 10 * time.Second + AcceptableClockSkew = 5 * time.Second JtiClaim = "jti" SidClaim = "sid" diff --git a/pkg/mock/openid.go b/pkg/mock/openid.go index 20d37d3..e8bde36 100644 --- a/pkg/mock/openid.go +++ b/pkg/mock/openid.go @@ -367,14 +367,16 @@ func (ip *IdentityProviderHandler) Token(w http.ResponseWriter, r *http.Request) } expires := int64(1200) + iat := time.Now().Truncate(time.Second) + exp := iat.Add(time.Duration(expires) * time.Second) sub := uuid.New().String() accessToken := jwt.New() accessToken.Set("sub", sub) accessToken.Set("iss", ip.Provider.GetOpenIDConfiguration().Issuer) accessToken.Set("acr", auth.AcrLevel) - accessToken.Set("iat", time.Now().Unix()) - accessToken.Set("exp", time.Now().Unix()+expires) + accessToken.Set("iat", iat.Unix()) + accessToken.Set("exp", exp.Unix()) accessToken.Set("jti", uuid.NewString()) signedAccessToken, err := ip.signToken(accessToken) if err != nil { @@ -390,8 +392,8 @@ func (ip *IdentityProviderHandler) Token(w http.ResponseWriter, r *http.Request) idToken.Set("locale", auth.Locale) idToken.Set("nonce", auth.Nonce) idToken.Set("acr", auth.AcrLevel) - idToken.Set("iat", time.Now().Unix()) - idToken.Set("exp", time.Now().Unix()+expires) + idToken.Set("iat", iat.Unix()) + idToken.Set("exp", exp.Unix()) idToken.Set("jti", uuid.NewString()) // If the sid claim should be in token and in active session diff --git a/pkg/openid/client/client.go b/pkg/openid/client/client.go index 04a9327..f0184db 100644 --- a/pkg/openid/client/client.go +++ b/pkg/openid/client/client.go @@ -105,7 +105,7 @@ func (c client) MakeAssertion(expiration time.Duration) (string, error) { providerCfg := c.config().Provider() key := clientCfg.GetClientJWK() - iat := time.Now() + iat := time.Now().Truncate(time.Second) exp := iat.Add(expiration) errs := make([]error, 0) diff --git a/pkg/openid/tokens.go b/pkg/openid/tokens.go index 5882b4c..f43c5e6 100644 --- a/pkg/openid/tokens.go +++ b/pkg/openid/tokens.go @@ -51,7 +51,7 @@ func (in *IDToken) Validate(cfg openidconfig.Config, nonce string) error { jwtlib.WithAudience(clientConfig.GetClientID()), jwtlib.WithClaimValue("nonce", nonce), jwtlib.WithIssuer(openIDconfig.Issuer), - jwtlib.WithAcceptableSkew(5 * time.Second), + jwtlib.WithAcceptableSkew(jwt.AcceptableClockSkew), } if openIDconfig.SidClaimRequired() { diff --git a/pkg/session/session_id_test.go b/pkg/session/session_id_test.go index 56ca83a..6df419a 100644 --- a/pkg/session/session_id_test.go +++ b/pkg/session/session_id_test.go @@ -137,12 +137,14 @@ func params(key, value string) url.Values { } func newIDToken(extraClaims map[string]string) *openid.IDToken { + now := time.Now().Truncate(time.Second) + idToken := jwtlib.New() idToken.Set("sub", "test") idToken.Set("iss", "test") idToken.Set("aud", "test") - idToken.Set("iat", time.Now().Unix()) - idToken.Set("exp", time.Now().Add(time.Hour).Unix()) + idToken.Set("iat", now.Unix()) + idToken.Set("exp", now.Add(time.Hour).Unix()) for claim, value := range extraClaims { if len(claim) > 0 {