From e730da143887486f65c615a92e6881726b0bf3d9 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 28 Aug 2020 08:15:12 -0700 Subject: [PATCH] fix: referesh JWKS public keys upon failure (#10368) fixes #10359 --- .github/workflows/go.yml | 2 +- cmd/config/identity/openid/jwt.go | 16 +++++++++++++++- cmd/config/identity/openid/jwt_test.go | 3 +++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index f39b8996b..770a9b023 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -40,7 +40,7 @@ jobs: sudo apt-get install devscripts shellcheck nancy_version=$(curl --retry 10 -Ls -o /dev/null -w "%{url_effective}" https://github.com/sonatype-nexus-community/nancy/releases/latest | sed "s/https:\/\/github.com\/sonatype-nexus-community\/nancy\/releases\/tag\///") curl -L -o nancy https://github.com/sonatype-nexus-community/nancy/releases/download/${nancy_version}/nancy-linux.amd64-${nancy_version} && chmod +x nancy - go list -m all | ./nancy + go list -m all | ./nancy sleuth make diff -au <(gofmt -s -d cmd) <(printf "") diff -au <(gofmt -s -d pkg) <(printf "") diff --git a/cmd/config/identity/openid/jwt.go b/cmd/config/identity/openid/jwt.go index cbb1592e3..560595911 100644 --- a/cmd/config/identity/openid/jwt.go +++ b/cmd/config/identity/openid/jwt.go @@ -25,6 +25,7 @@ import ( "net/http" "strconv" "strings" + "sync" "time" jwtgo "github.com/dgrijalva/jwt-go" @@ -49,10 +50,14 @@ type Config struct { publicKeys map[string]crypto.PublicKey transport *http.Transport closeRespFn func(io.ReadCloser) + mutex *sync.Mutex } // PopulatePublicKey - populates a new publickey from the JWKS URL. func (r *Config) PopulatePublicKey() error { + r.mutex.Lock() + defer r.mutex.Unlock() + if r.JWKS.URL == nil || r.JWKS.URL.String() == "" { return nil } @@ -185,7 +190,15 @@ func (p *JWT) Validate(token, dsecs string) (map[string]interface{}, error) { var claims jwtgo.MapClaims jwtToken, err := jp.ParseWithClaims(token, &claims, keyFuncCallback) if err != nil { - return nil, err + // Re-populate the public key in-case the JWKS + // pubkeys are refreshed + if err = p.PopulatePublicKey(); err != nil { + return nil, err + } + jwtToken, err = jwtgo.ParseWithClaims(token, &claims, keyFuncCallback) + if err != nil { + return nil, err + } } if !jwtToken.Valid { @@ -317,6 +330,7 @@ func LookupConfig(kvs config.KVS, transport *http.Transport, closeRespFn func(io ClientID: env.Get(EnvIdentityOpenIDClientID, kvs.Get(ClientID)), transport: transport, closeRespFn: closeRespFn, + mutex: &sync.Mutex{}, // allocate for copying } configURL := env.Get(EnvIdentityOpenIDURL, kvs.Get(ConfigURL)) diff --git a/cmd/config/identity/openid/jwt_test.go b/cmd/config/identity/openid/jwt_test.go index cf7380e8c..2af1b3ebd 100644 --- a/cmd/config/identity/openid/jwt_test.go +++ b/cmd/config/identity/openid/jwt_test.go @@ -20,6 +20,7 @@ import ( "crypto" "encoding/json" "net/url" + "sync" "testing" "time" @@ -89,6 +90,7 @@ func TestJWTAzureFail(t *testing.T) { } cfg := Config{} + cfg.mutex = &sync.Mutex{} cfg.JWKS.URL = u1 cfg.publicKeys = keys jwt := NewJWT(cfg) @@ -136,6 +138,7 @@ func TestJWT(t *testing.T) { } cfg := Config{} + cfg.mutex = &sync.Mutex{} cfg.JWKS.URL = u1 cfg.publicKeys = keys jwt := NewJWT(cfg)