Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add claimMapping enforcement #2233

Merged
merged 7 commits into from
Jan 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions connector/oidc/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ type Config struct {
// PromptType will be used fot the prompt parameter (when offline_access, by default prompt=consent)
PromptType string `json:"promptType"`

// OverrideClaimMapping will be used to override the options defined in claimMappings.
// i.e. if there are 'email' and `preferred_email` claims available, by default Dex will always use the `email` claim independent of the ClaimMapping.EmailKey.
// This setting allows you to override the default behavior of Dex and enforce the mappings defined in `claimMapping`.
OverrideClaimMapping bool `json:"overrideClaimMapping"` // defaults to false

ClaimMapping struct {
// Configurable key which contains the preferred username claims
PreferredUsernameKey string `json:"preferred_username"` // defaults to "preferred_username"
Expand Down Expand Up @@ -153,6 +158,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
promptType: c.PromptType,
userIDKey: c.UserIDKey,
userNameKey: c.UserNameKey,
overrideClaimMapping: c.OverrideClaimMapping,
preferredUsernameKey: c.ClaimMapping.PreferredUsernameKey,
emailKey: c.ClaimMapping.EmailKey,
groupsKey: c.ClaimMapping.GroupsKey,
Expand All @@ -178,6 +184,7 @@ type oidcConnector struct {
promptType string
userIDKey string
userNameKey string
overrideClaimMapping bool
preferredUsernameKey string
emailKey string
groupsKey string
Expand Down Expand Up @@ -289,7 +296,7 @@ func (c *oidcConnector) createIdentity(ctx context.Context, identity connector.I
}

preferredUsername, found := claims["preferred_username"].(string)
if !found {
if (!found || c.overrideClaimMapping) && c.preferredUsernameKey != "" {
preferredUsername, _ = claims[c.preferredUsernameKey].(string)
}

Expand All @@ -304,7 +311,7 @@ func (c *oidcConnector) createIdentity(ctx context.Context, identity connector.I
var email string
emailKey := "email"
email, found = claims[emailKey].(string)
if !found && c.emailKey != "" {
if (!found || c.overrideClaimMapping) && c.emailKey != "" {
emailKey = c.emailKey
email, found = claims[emailKey].(string)
}
Expand All @@ -326,7 +333,7 @@ func (c *oidcConnector) createIdentity(ctx context.Context, identity connector.I
if c.insecureEnableGroups {
groupsKey := "groups"
vs, found := claims[groupsKey].([]interface{})
if !found {
if (!found || c.overrideClaimMapping) && c.groupsKey != "" {
groupsKey = c.groupsKey
vs, found = claims[groupsKey].([]interface{})
}
Expand Down
38 changes: 38 additions & 0 deletions connector/oidc/oidc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func TestHandleCallback(t *testing.T) {
name string
userIDKey string
userNameKey string
overrideClaimMapping bool
preferredUsernameKey string
emailKey string
groupsKey string
Expand Down Expand Up @@ -92,6 +93,23 @@ func TestHandleCallback(t *testing.T) {
"email_verified": true,
},
},
{
name: "overrideWithCustomEmailClaim",
userIDKey: "", // not configured
userNameKey: "", // not configured
overrideClaimMapping: true,
emailKey: "custommail",
expectUserID: "subvalue",
expectUserName: "namevalue",
expectedEmailField: "customemailvalue",
token: map[string]interface{}{
"sub": "subvalue",
"name": "namevalue",
"email": "emailvalue",
"custommail": "customemailvalue",
"email_verified": true,
},
},
{
name: "email_verified not in claims, configured to be skipped",
insecureSkipEmailVerified: true,
Expand Down Expand Up @@ -234,6 +252,25 @@ func TestHandleCallback(t *testing.T) {
"cognito:groups": []string{"group3", "group4"},
},
},
{
name: "customGroupsKeyDespiteGroupsProvidedButOverride",
overrideClaimMapping: true,
groupsKey: "cognito:groups",
expectUserID: "subvalue",
expectUserName: "namevalue",
expectedEmailField: "emailvalue",
expectGroups: []string{"group3", "group4"},
scopes: []string{"groups"},
insecureSkipEmailVerified: true,
token: map[string]interface{}{
"sub": "subvalue",
"name": "namevalue",
"user_name": "username",
"email": "emailvalue",
"groups": []string{"group1", "group2"},
"cognito:groups": []string{"group3", "group4"},
},
},
}

for _, tc := range tests {
Expand Down Expand Up @@ -263,6 +300,7 @@ func TestHandleCallback(t *testing.T) {
InsecureSkipEmailVerified: tc.insecureSkipEmailVerified,
InsecureEnableGroups: true,
BasicAuthUnsupported: &basicAuth,
OverrideClaimMapping: tc.overrideClaimMapping,
}
config.ClaimMapping.PreferredUsernameKey = tc.preferredUsernameKey
config.ClaimMapping.EmailKey = tc.emailKey
Expand Down