Skip to content

Commit

Permalink
Fix if the first fetching public keys failed from Hydra
Browse files Browse the repository at this point in the history
Added retry when oidc verifier is not exists when new request comes

PiperOrigin-RevId: 328377540
Change-Id: If3cc37ad7859347e1fa9c988b63e4cda9e79062d
  • Loading branch information
chaopeng authored and copybara-github committed Aug 25, 2020
1 parent 03463f1 commit 249a8a4
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 14 deletions.
37 changes: 24 additions & 13 deletions lib/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,24 +115,35 @@ type Checker struct {
// level field.
transformIdentity func(*ga4gh.Identity) *ga4gh.Identity
// init the verifier.AccessTokenVerifier
init sync.Once
mutex sync.Mutex
// access token verifier
verifier verifier.AccessTokenVerifier
// use userinfo instead of the token itself to verify access token.
useUserinfoVerifyToken bool
}

func (s *Checker) getVerifier(ctx context.Context) (verifier.AccessTokenVerifier, error) {
var err error
s.init.Do(func() {
s.verifier, err = verifier.NewAccessTokenVerifier(ctx, s.issuer, s.useUserinfoVerifyToken)
})
// TODO: We use lazy load for verifier creation since now Hydra
// and IC/DAM are deployed in a same container. Hydra is not available before
// IC/DAM startup completed. We should separate Hydra and IC/DAM to 2
// containers after that we should fetch oidc public key when service
// starts and exit with error.

if err != nil {
return nil, err
if s.verifier != nil {
return s.verifier, nil
}

return s.verifier, nil
s.mutex.Lock()
defer s.mutex.Unlock()

// s.verifier maybe available after the waiting.
if s.verifier != nil {
return s.verifier, nil
}

var err error
s.verifier, err = verifier.NewAccessTokenVerifier(ctx, s.issuer, s.useUserinfoVerifyToken)
return s.verifier, err
}

// NewChecker creates checker for authorization check.
Expand All @@ -144,11 +155,11 @@ func (s *Checker) getVerifier(ctx context.Context) (verifier.AccessTokenVerifier
// transformIdentity: transform as needed, will run just after token convert to identity.
func NewChecker(logger *logging.Client, issuer string, permissions *permissions.Permissions, fetchClientSecrets func() (map[string]string, error), transformIdentity func(*ga4gh.Identity) *ga4gh.Identity, useUserinfoVerifyToken bool) *Checker {
return &Checker{
logger: logger,
issuer: issuer,
permissions: permissions,
fetchClientSecrets: fetchClientSecrets,
transformIdentity: transformIdentity,
logger: logger,
issuer: issuer,
permissions: permissions,
fetchClientSecrets: fetchClientSecrets,
transformIdentity: transformIdentity,
useUserinfoVerifyToken: useUserinfoVerifyToken,
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/verifier/oidc_jwt_sig_verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type oidcJwtSigVerifier struct {
func newOIDCSigVerifier(ctx context.Context, issuer string) (*oidcJwtSigVerifier, error) {
p, err := oidc.NewProvider(ctx, issuer)
if err != nil {
return nil, errutil.WithErrorReason(errCreateVerifierFailed, status.Errorf(codes.Unavailable, "create oidc failed: %v", err))
return nil, errutil.WithErrorReason(errCreateVerifierFailed, status.Errorf(codes.Unavailable, "create oidc failed, usually caused by service does not able reach to Hydra jwks endpoint: %v", err))
}

v := p.Verifier(&oidc.Config{
Expand Down

0 comments on commit 249a8a4

Please sign in to comment.