fix: referesh JWKS public keys upon failure (#10368)

fixes #10359
master
Harshavardhana 4 years ago committed by GitHub
parent 46ee8659b4
commit e730da1438
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .github/workflows/go.yml
  2. 16
      cmd/config/identity/openid/jwt.go
  3. 3
      cmd/config/identity/openid/jwt_test.go

@ -40,7 +40,7 @@ jobs:
sudo apt-get install devscripts shellcheck 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\///") 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 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 make
diff -au <(gofmt -s -d cmd) <(printf "") diff -au <(gofmt -s -d cmd) <(printf "")
diff -au <(gofmt -s -d pkg) <(printf "") diff -au <(gofmt -s -d pkg) <(printf "")

@ -25,6 +25,7 @@ import (
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
jwtgo "github.com/dgrijalva/jwt-go" jwtgo "github.com/dgrijalva/jwt-go"
@ -49,10 +50,14 @@ type Config struct {
publicKeys map[string]crypto.PublicKey publicKeys map[string]crypto.PublicKey
transport *http.Transport transport *http.Transport
closeRespFn func(io.ReadCloser) closeRespFn func(io.ReadCloser)
mutex *sync.Mutex
} }
// PopulatePublicKey - populates a new publickey from the JWKS URL. // PopulatePublicKey - populates a new publickey from the JWKS URL.
func (r *Config) PopulatePublicKey() error { func (r *Config) PopulatePublicKey() error {
r.mutex.Lock()
defer r.mutex.Unlock()
if r.JWKS.URL == nil || r.JWKS.URL.String() == "" { if r.JWKS.URL == nil || r.JWKS.URL.String() == "" {
return nil return nil
} }
@ -185,7 +190,15 @@ func (p *JWT) Validate(token, dsecs string) (map[string]interface{}, error) {
var claims jwtgo.MapClaims var claims jwtgo.MapClaims
jwtToken, err := jp.ParseWithClaims(token, &claims, keyFuncCallback) jwtToken, err := jp.ParseWithClaims(token, &claims, keyFuncCallback)
if err != nil { 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 { 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)), ClientID: env.Get(EnvIdentityOpenIDClientID, kvs.Get(ClientID)),
transport: transport, transport: transport,
closeRespFn: closeRespFn, closeRespFn: closeRespFn,
mutex: &sync.Mutex{}, // allocate for copying
} }
configURL := env.Get(EnvIdentityOpenIDURL, kvs.Get(ConfigURL)) configURL := env.Get(EnvIdentityOpenIDURL, kvs.Get(ConfigURL))

@ -20,6 +20,7 @@ import (
"crypto" "crypto"
"encoding/json" "encoding/json"
"net/url" "net/url"
"sync"
"testing" "testing"
"time" "time"
@ -89,6 +90,7 @@ func TestJWTAzureFail(t *testing.T) {
} }
cfg := Config{} cfg := Config{}
cfg.mutex = &sync.Mutex{}
cfg.JWKS.URL = u1 cfg.JWKS.URL = u1
cfg.publicKeys = keys cfg.publicKeys = keys
jwt := NewJWT(cfg) jwt := NewJWT(cfg)
@ -136,6 +138,7 @@ func TestJWT(t *testing.T) {
} }
cfg := Config{} cfg := Config{}
cfg.mutex = &sync.Mutex{}
cfg.JWKS.URL = u1 cfg.JWKS.URL = u1
cfg.publicKeys = keys cfg.publicKeys = keys
jwt := NewJWT(cfg) jwt := NewJWT(cfg)

Loading…
Cancel
Save