git.iko.soy/typeable/oauth2-proxy
on master help sign in
Fallback to UserInfo is User ID claim not present (#560)
160bbafJoel Speed
CHANGELOG.md+1
@@ -55,6 +55,7 @@
55
55
56## Changes since v5.1.1
56## Changes since v5.1.1
57
57
58+- [#560](https://github.com/oauth2-proxy/oauth2-proxy/pull/560) Fallback to UserInfo is User ID claim not present (@JoelSpeed)
58- [#598](https://github.com/oauth2-proxy/oauth2-proxy/pull/598) acr_values no longer sent to IdP when empty (@ScottGuymer)
59- [#598](https://github.com/oauth2-proxy/oauth2-proxy/pull/598) acr_values no longer sent to IdP when empty (@ScottGuymer)
59- [#548](https://github.com/oauth2-proxy/oauth2-proxy/pull/548) Separate logging options out of main options structure (@JoelSpeed)
60- [#548](https://github.com/oauth2-proxy/oauth2-proxy/pull/548) Separate logging options out of main options structure (@JoelSpeed)
60- [#536](https://github.com/oauth2-proxy/oauth2-proxy/pull/536) Improvements to Session State code (@JoelSpeed)
61- [#536](https://github.com/oauth2-proxy/oauth2-proxy/pull/536) Improvements to Session State code (@JoelSpeed)
providers/oidc.go+9−10
@@ -199,7 +199,7 @@ func (p *OIDCProvider) createSessionStateInternal(ctx context.Context, rawIDToke
199
199
200 claims, err := p.findClaimsFromIDToken(ctx, idToken, accessToken, p.ProfileURL.String())
200 claims, err := p.findClaimsFromIDToken(ctx, idToken, accessToken, p.ProfileURL.String())
201 if err != nil {
201 if err != nil {
202− return nil, fmt.Errorf("couldn't extract claims from id_token (%e)", err)
202+ return nil, fmt.Errorf("couldn't extract claims from id_token (%v)", err)
203 }
203 }
204
204
205 newSession.IDToken = rawIDToken
205 newSession.IDToken = rawIDToken
@@ -243,20 +243,19 @@ func (p *OIDCProvider) findClaimsFromIDToken(ctx context.Context, idToken *oidc.
243 }
243 }
244
244
245 userID := claims.rawClaims[p.UserIDClaim]
245 userID := claims.rawClaims[p.UserIDClaim]
246− if userID == nil {
246+ if userID != nil {
247− return nil, fmt.Errorf("claims did not contains the required user-id-claim '%s'", p.UserIDClaim)
247+ claims.UserID = fmt.Sprint(userID)
248 }
248 }
249− claims.UserID = fmt.Sprint(userID)
250
249
250+ // userID claim was not present or was empty in the ID Token
251− if p.UserIDClaim == emailClaim && claims.UserID == "" {
251+ if claims.UserID == "" {
252 if profileURL == "" {
252 if profileURL == "" {
253− return nil, fmt.Errorf("id_token did not contain an email")
253+ return nil, fmt.Errorf("id_token did not contain user ID claim (%q)", p.UserIDClaim)
254 }
254 }
255
255
256 // If the userinfo endpoint profileURL is defined, then there is a chance the userinfo
256 // If the userinfo endpoint profileURL is defined, then there is a chance the userinfo
257 // contents at the profileURL contains the email.
257 // contents at the profileURL contains the email.
258 // Make a query to the userinfo endpoint, and attempt to locate the email from there.
258 // Make a query to the userinfo endpoint, and attempt to locate the email from there.
259−
260 req, err := http.NewRequestWithContext(ctx, "GET", profileURL, nil)
259 req, err := http.NewRequestWithContext(ctx, "GET", profileURL, nil)
261 if err != nil {
260 if err != nil {
262 return nil, err
261 return nil, err
@@ -268,12 +267,12 @@ func (p *OIDCProvider) findClaimsFromIDToken(ctx context.Context, idToken *oidc.
268 return nil, err
267 return nil, err
269 }
268 }
270
269
271− email, err := respJSON.Get("email").String()
270+ userID, err := respJSON.Get(p.UserIDClaim).String()
272 if err != nil {
271 if err != nil {
273− return nil, fmt.Errorf("neither id_token nor userinfo endpoint contained an email")
272+ return nil, fmt.Errorf("neither id_token nor userinfo endpoint contained user ID claim (%q)", p.UserIDClaim)
274 }
273 }
275
274
276− claims.UserID = email
275+ claims.UserID = userID
277 }
276 }
278
277
279 return claims, nil
278 return claims, nil