From dc7e647ec55e0b056cd540d5c19f7d4e56ecd569 Mon Sep 17 00:00:00 2001 From: Cyrille Nofficial Date: Fri, 17 Apr 2020 10:01:52 +0200 Subject: [PATCH] Add parameter configuration to override email claim key --- Documentation/connectors/oidc.md | 5 +++++ connector/oidc/oidc.go | 14 ++++++++++++-- connector/oidc/oidc_test.go | 17 +++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Documentation/connectors/oidc.md b/Documentation/connectors/oidc.md index c472e303ff..4df28915e2 100644 --- a/Documentation/connectors/oidc.md +++ b/Documentation/connectors/oidc.md @@ -56,6 +56,11 @@ connectors: # - email # - groups + # Some providers return no standard email claim key (ex: 'mail') + # Override email claim key + # Default is "email" + # emailClaim: email + # Some providers return claims without "email_verified", when they had no usage of emails verification in enrollment process # or if they are acting as a proxy for another IDP etc AWS Cognito with an upstream SAML IDP # This can be overridden with the below option diff --git a/connector/oidc/oidc.go b/connector/oidc/oidc.go index 675e4b95df..11f08c4cc2 100644 --- a/connector/oidc/oidc.go +++ b/connector/oidc/oidc.go @@ -55,6 +55,9 @@ type Config struct { // Configurable key which contains the user name claim UserNameKey string `json:"userNameKey"` + // EmailClaim override email claim key. Defaults to "email" + EmailClaim string `json:"emailClaim"` + // PromptType will be used fot the prompt parameter (when offline_access, by default prompt=consent) PromptType string `json:"promptType"` } @@ -109,6 +112,11 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e endpoint.AuthStyle = oauth2.AuthStyleInParams } + emailClaim := "email" + if len(c.EmailClaim) > 0 { + emailClaim = c.EmailClaim + } + scopes := []string{oidc.ScopeOpenID} if len(c.Scopes) > 0 { scopes = append(scopes, c.Scopes...) @@ -143,6 +151,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e getUserInfo: c.GetUserInfo, userIDKey: c.UserIDKey, userNameKey: c.UserNameKey, + emailClaim: emailClaim, promptType: c.PromptType, }, nil } @@ -165,6 +174,7 @@ type oidcConnector struct { getUserInfo bool userIDKey string userNameKey string + emailClaim string promptType string } @@ -281,9 +291,9 @@ func (c *oidcConnector) createIdentity(ctx context.Context, identity connector.I } } - email, found := claims["email"].(string) + email, found := claims[c.emailClaim].(string) if !found && hasEmailScope { - return identity, errors.New("missing \"email\" claim") + return identity, fmt.Errorf("missing \"%s\" claim", c.emailClaim) } emailVerified, found := claims["email_verified"].(bool) diff --git a/connector/oidc/oidc_test.go b/connector/oidc/oidc_test.go index 52afa15804..7d88aabac1 100644 --- a/connector/oidc/oidc_test.go +++ b/connector/oidc/oidc_test.go @@ -51,6 +51,7 @@ func TestHandleCallback(t *testing.T) { userNameKey string insecureSkipEmailVerified bool scopes []string + emailClaim string expectUserID string expectUserName string expectedEmailField string @@ -70,6 +71,21 @@ func TestHandleCallback(t *testing.T) { "email_verified": true, }, }, + { + name: "customEmailClaim", + userIDKey: "", // not configured + userNameKey: "", // not configured + emailClaim: "mail", + expectUserID: "subvalue", + expectUserName: "namevalue", + expectedEmailField: "emailvalue", + token: map[string]interface{}{ + "sub": "subvalue", + "name": "namevalue", + "mail": "emailvalue", + "email_verified": true, + }, + }, { name: "email_verified not in claims, configured to be skipped", insecureSkipEmailVerified: true, @@ -161,6 +177,7 @@ func TestHandleCallback(t *testing.T) { RedirectURI: fmt.Sprintf("%s/callback", serverURL), UserIDKey: tc.userIDKey, UserNameKey: tc.userNameKey, + EmailClaim: tc.emailClaim, InsecureSkipEmailVerified: tc.insecureSkipEmailVerified, BasicAuthUnsupported: &basicAuth, }