Merge pull request #2233 from Happy2C0de/add-claimMapping-enforcement
Add claimMapping enforcement
This commit is contained in:
commit
73ce1eb110
2 changed files with 48 additions and 3 deletions
|
@ -56,6 +56,11 @@ type Config struct {
|
||||||
// PromptType will be used fot the prompt parameter (when offline_access, by default prompt=consent)
|
// PromptType will be used fot the prompt parameter (when offline_access, by default prompt=consent)
|
||||||
PromptType string `json:"promptType"`
|
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 {
|
ClaimMapping struct {
|
||||||
// Configurable key which contains the preferred username claims
|
// Configurable key which contains the preferred username claims
|
||||||
PreferredUsernameKey string `json:"preferred_username"` // defaults to "preferred_username"
|
PreferredUsernameKey string `json:"preferred_username"` // defaults to "preferred_username"
|
||||||
|
@ -153,6 +158,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
|
||||||
promptType: c.PromptType,
|
promptType: c.PromptType,
|
||||||
userIDKey: c.UserIDKey,
|
userIDKey: c.UserIDKey,
|
||||||
userNameKey: c.UserNameKey,
|
userNameKey: c.UserNameKey,
|
||||||
|
overrideClaimMapping: c.OverrideClaimMapping,
|
||||||
preferredUsernameKey: c.ClaimMapping.PreferredUsernameKey,
|
preferredUsernameKey: c.ClaimMapping.PreferredUsernameKey,
|
||||||
emailKey: c.ClaimMapping.EmailKey,
|
emailKey: c.ClaimMapping.EmailKey,
|
||||||
groupsKey: c.ClaimMapping.GroupsKey,
|
groupsKey: c.ClaimMapping.GroupsKey,
|
||||||
|
@ -178,6 +184,7 @@ type oidcConnector struct {
|
||||||
promptType string
|
promptType string
|
||||||
userIDKey string
|
userIDKey string
|
||||||
userNameKey string
|
userNameKey string
|
||||||
|
overrideClaimMapping bool
|
||||||
preferredUsernameKey string
|
preferredUsernameKey string
|
||||||
emailKey string
|
emailKey string
|
||||||
groupsKey string
|
groupsKey string
|
||||||
|
@ -289,7 +296,7 @@ func (c *oidcConnector) createIdentity(ctx context.Context, identity connector.I
|
||||||
}
|
}
|
||||||
|
|
||||||
preferredUsername, found := claims["preferred_username"].(string)
|
preferredUsername, found := claims["preferred_username"].(string)
|
||||||
if !found {
|
if (!found || c.overrideClaimMapping) && c.preferredUsernameKey != "" {
|
||||||
preferredUsername, _ = claims[c.preferredUsernameKey].(string)
|
preferredUsername, _ = claims[c.preferredUsernameKey].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +311,7 @@ func (c *oidcConnector) createIdentity(ctx context.Context, identity connector.I
|
||||||
var email string
|
var email string
|
||||||
emailKey := "email"
|
emailKey := "email"
|
||||||
email, found = claims[emailKey].(string)
|
email, found = claims[emailKey].(string)
|
||||||
if !found && c.emailKey != "" {
|
if (!found || c.overrideClaimMapping) && c.emailKey != "" {
|
||||||
emailKey = c.emailKey
|
emailKey = c.emailKey
|
||||||
email, found = claims[emailKey].(string)
|
email, found = claims[emailKey].(string)
|
||||||
}
|
}
|
||||||
|
@ -326,7 +333,7 @@ func (c *oidcConnector) createIdentity(ctx context.Context, identity connector.I
|
||||||
if c.insecureEnableGroups {
|
if c.insecureEnableGroups {
|
||||||
groupsKey := "groups"
|
groupsKey := "groups"
|
||||||
vs, found := claims[groupsKey].([]interface{})
|
vs, found := claims[groupsKey].([]interface{})
|
||||||
if !found {
|
if (!found || c.overrideClaimMapping) && c.groupsKey != "" {
|
||||||
groupsKey = c.groupsKey
|
groupsKey = c.groupsKey
|
||||||
vs, found = claims[groupsKey].([]interface{})
|
vs, found = claims[groupsKey].([]interface{})
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ func TestHandleCallback(t *testing.T) {
|
||||||
name string
|
name string
|
||||||
userIDKey string
|
userIDKey string
|
||||||
userNameKey string
|
userNameKey string
|
||||||
|
overrideClaimMapping bool
|
||||||
preferredUsernameKey string
|
preferredUsernameKey string
|
||||||
emailKey string
|
emailKey string
|
||||||
groupsKey string
|
groupsKey string
|
||||||
|
@ -92,6 +93,23 @@ func TestHandleCallback(t *testing.T) {
|
||||||
"email_verified": true,
|
"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",
|
name: "email_verified not in claims, configured to be skipped",
|
||||||
insecureSkipEmailVerified: true,
|
insecureSkipEmailVerified: true,
|
||||||
|
@ -234,6 +252,25 @@ func TestHandleCallback(t *testing.T) {
|
||||||
"cognito:groups": []string{"group3", "group4"},
|
"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 {
|
for _, tc := range tests {
|
||||||
|
@ -263,6 +300,7 @@ func TestHandleCallback(t *testing.T) {
|
||||||
InsecureSkipEmailVerified: tc.insecureSkipEmailVerified,
|
InsecureSkipEmailVerified: tc.insecureSkipEmailVerified,
|
||||||
InsecureEnableGroups: true,
|
InsecureEnableGroups: true,
|
||||||
BasicAuthUnsupported: &basicAuth,
|
BasicAuthUnsupported: &basicAuth,
|
||||||
|
OverrideClaimMapping: tc.overrideClaimMapping,
|
||||||
}
|
}
|
||||||
config.ClaimMapping.PreferredUsernameKey = tc.preferredUsernameKey
|
config.ClaimMapping.PreferredUsernameKey = tc.preferredUsernameKey
|
||||||
config.ClaimMapping.EmailKey = tc.emailKey
|
config.ClaimMapping.EmailKey = tc.emailKey
|
||||||
|
|
Reference in a new issue