Make OIDC username key configurable
Signed-off-by: Josh Winters <jwinters@pivotal.io> Co-authored-by: Mark Huang <mhuang@pivotal.io> Signed-off-by: Rui Yang <ruiya@vmware.com>
This commit is contained in:
parent
19cd9cc65c
commit
9a4e0fcd00
2 changed files with 35 additions and 5 deletions
|
@ -55,6 +55,9 @@ type Config struct {
|
||||||
// Configurable key which contains the user name claim
|
// Configurable key which contains the user name claim
|
||||||
UserNameKey string `json:"userNameKey"`
|
UserNameKey string `json:"userNameKey"`
|
||||||
|
|
||||||
|
// Configurable key which contains the username claims
|
||||||
|
PreferredUsernameKey string `json:"preferredUsernameKey"` // defaults to "username"
|
||||||
|
|
||||||
// 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"`
|
||||||
}
|
}
|
||||||
|
@ -143,6 +146,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
|
||||||
getUserInfo: c.GetUserInfo,
|
getUserInfo: c.GetUserInfo,
|
||||||
userIDKey: c.UserIDKey,
|
userIDKey: c.UserIDKey,
|
||||||
userNameKey: c.UserNameKey,
|
userNameKey: c.UserNameKey,
|
||||||
|
preferredUsernameKey: c.PreferredUsernameKey,
|
||||||
promptType: c.PromptType,
|
promptType: c.PromptType,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -165,6 +169,7 @@ type oidcConnector struct {
|
||||||
getUserInfo bool
|
getUserInfo bool
|
||||||
userIDKey string
|
userIDKey string
|
||||||
userNameKey string
|
userNameKey string
|
||||||
|
preferredUsernameKey string
|
||||||
promptType string
|
promptType string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,6 +301,11 @@ func (c *oidcConnector) createIdentity(ctx context.Context, identity connector.I
|
||||||
}
|
}
|
||||||
hostedDomain, _ := claims["hd"].(string)
|
hostedDomain, _ := claims["hd"].(string)
|
||||||
|
|
||||||
|
if c.preferredUsernameKey == "" {
|
||||||
|
c.preferredUsernameKey = "username"
|
||||||
|
}
|
||||||
|
username, _ := claims[c.preferredUsernameKey].(string)
|
||||||
|
|
||||||
if len(c.hostedDomains) > 0 {
|
if len(c.hostedDomains) > 0 {
|
||||||
found := false
|
found := false
|
||||||
for _, domain := range c.hostedDomains {
|
for _, domain := range c.hostedDomains {
|
||||||
|
@ -322,6 +332,7 @@ func (c *oidcConnector) createIdentity(ctx context.Context, identity connector.I
|
||||||
identity = connector.Identity{
|
identity = connector.Identity{
|
||||||
UserID: idToken.Subject,
|
UserID: idToken.Subject,
|
||||||
Username: name,
|
Username: name,
|
||||||
|
PreferredUsername: username,
|
||||||
Email: email,
|
Email: email,
|
||||||
EmailVerified: emailVerified,
|
EmailVerified: emailVerified,
|
||||||
ConnectorData: connData,
|
ConnectorData: connData,
|
||||||
|
|
|
@ -49,10 +49,12 @@ func TestHandleCallback(t *testing.T) {
|
||||||
name string
|
name string
|
||||||
userIDKey string
|
userIDKey string
|
||||||
userNameKey string
|
userNameKey string
|
||||||
|
preferredUsernameKey string
|
||||||
insecureSkipEmailVerified bool
|
insecureSkipEmailVerified bool
|
||||||
scopes []string
|
scopes []string
|
||||||
expectUserID string
|
expectUserID string
|
||||||
expectUserName string
|
expectUserName string
|
||||||
|
expectPreferredUsername string
|
||||||
expectedEmailField string
|
expectedEmailField string
|
||||||
token map[string]interface{}
|
token map[string]interface{}
|
||||||
}{
|
}{
|
||||||
|
@ -108,6 +110,21 @@ func TestHandleCallback(t *testing.T) {
|
||||||
"email_verified": true,
|
"email_verified": true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "withPreferredUsernameKey",
|
||||||
|
preferredUsernameKey: "preferred_username",
|
||||||
|
expectUserID: "subvalue",
|
||||||
|
expectUserName: "namevalue",
|
||||||
|
expectPreferredUsername: "usernamevalue",
|
||||||
|
expectedEmailField: "emailvalue",
|
||||||
|
token: map[string]interface{}{
|
||||||
|
"sub": "subvalue",
|
||||||
|
"name": "namevalue",
|
||||||
|
"preferred_username": "usernamevalue",
|
||||||
|
"email": "emailvalue",
|
||||||
|
"email_verified": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "emptyEmailScope",
|
name: "emptyEmailScope",
|
||||||
expectUserID: "subvalue",
|
expectUserID: "subvalue",
|
||||||
|
@ -161,6 +178,7 @@ func TestHandleCallback(t *testing.T) {
|
||||||
RedirectURI: fmt.Sprintf("%s/callback", serverURL),
|
RedirectURI: fmt.Sprintf("%s/callback", serverURL),
|
||||||
UserIDKey: tc.userIDKey,
|
UserIDKey: tc.userIDKey,
|
||||||
UserNameKey: tc.userNameKey,
|
UserNameKey: tc.userNameKey,
|
||||||
|
PreferredUsernameKey: tc.preferredUsernameKey,
|
||||||
InsecureSkipEmailVerified: tc.insecureSkipEmailVerified,
|
InsecureSkipEmailVerified: tc.insecureSkipEmailVerified,
|
||||||
BasicAuthUnsupported: &basicAuth,
|
BasicAuthUnsupported: &basicAuth,
|
||||||
}
|
}
|
||||||
|
@ -182,6 +200,7 @@ func TestHandleCallback(t *testing.T) {
|
||||||
|
|
||||||
expectEquals(t, identity.UserID, tc.expectUserID)
|
expectEquals(t, identity.UserID, tc.expectUserID)
|
||||||
expectEquals(t, identity.Username, tc.expectUserName)
|
expectEquals(t, identity.Username, tc.expectUserName)
|
||||||
|
expectEquals(t, identity.PreferredUsername, tc.expectPreferredUsername)
|
||||||
expectEquals(t, identity.Email, tc.expectedEmailField)
|
expectEquals(t, identity.Email, tc.expectedEmailField)
|
||||||
expectEquals(t, identity.EmailVerified, true)
|
expectEquals(t, identity.EmailVerified, true)
|
||||||
})
|
})
|
||||||
|
|
Reference in a new issue