From 160bbaf98e603fc4dfa18b19e39eccb05b0ad416 Mon Sep 17 00:00:00 2001 From: Joel Speed Date: Thu, 4 Jun 2020 17:41:29 +0100 Subject: [PATCH] Fallback to UserInfo is User ID claim not present (#560) Co-authored-by: Henry Jenkins --- CHANGELOG.md | 1 + providers/oidc.go | 19 +++++++++---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 024702c..97ecc27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ ## Changes since v5.1.1 +- [#560](https://github.com/oauth2-proxy/oauth2-proxy/pull/560) Fallback to UserInfo is User ID claim not present (@JoelSpeed) - [#598](https://github.com/oauth2-proxy/oauth2-proxy/pull/598) acr_values no longer sent to IdP when empty (@ScottGuymer) - [#548](https://github.com/oauth2-proxy/oauth2-proxy/pull/548) Separate logging options out of main options structure (@JoelSpeed) - [#536](https://github.com/oauth2-proxy/oauth2-proxy/pull/536) Improvements to Session State code (@JoelSpeed) diff --git a/providers/oidc.go b/providers/oidc.go index f419b5d..bc98dbb 100644 --- a/providers/oidc.go +++ b/providers/oidc.go @@ -199,7 +199,7 @@ func (p *OIDCProvider) createSessionStateInternal(ctx context.Context, rawIDToke claims, err := p.findClaimsFromIDToken(ctx, idToken, accessToken, p.ProfileURL.String()) if err != nil { - return nil, fmt.Errorf("couldn't extract claims from id_token (%e)", err) + return nil, fmt.Errorf("couldn't extract claims from id_token (%v)", err) } newSession.IDToken = rawIDToken @@ -243,20 +243,19 @@ func (p *OIDCProvider) findClaimsFromIDToken(ctx context.Context, idToken *oidc. } userID := claims.rawClaims[p.UserIDClaim] - if userID == nil { - return nil, fmt.Errorf("claims did not contains the required user-id-claim '%s'", p.UserIDClaim) + if userID != nil { + claims.UserID = fmt.Sprint(userID) } - claims.UserID = fmt.Sprint(userID) - if p.UserIDClaim == emailClaim && claims.UserID == "" { + // userID claim was not present or was empty in the ID Token + if claims.UserID == "" { if profileURL == "" { - return nil, fmt.Errorf("id_token did not contain an email") + return nil, fmt.Errorf("id_token did not contain user ID claim (%q)", p.UserIDClaim) } // If the userinfo endpoint profileURL is defined, then there is a chance the userinfo // contents at the profileURL contains the email. // Make a query to the userinfo endpoint, and attempt to locate the email from there. - req, err := http.NewRequestWithContext(ctx, "GET", profileURL, nil) if err != nil { return nil, err @@ -268,12 +267,12 @@ func (p *OIDCProvider) findClaimsFromIDToken(ctx context.Context, idToken *oidc. return nil, err } - email, err := respJSON.Get("email").String() + userID, err := respJSON.Get(p.UserIDClaim).String() if err != nil { - return nil, fmt.Errorf("neither id_token nor userinfo endpoint contained an email") + return nil, fmt.Errorf("neither id_token nor userinfo endpoint contained user ID claim (%q)", p.UserIDClaim) } - claims.UserID = email + claims.UserID = userID } return claims, nil