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:
Josh Winters 2019-02-27 15:12:11 -05:00 committed by Rui Yang
parent 19cd9cc65c
commit 9a4e0fcd00
2 changed files with 35 additions and 5 deletions

View File

@ -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 {
@ -320,11 +330,12 @@ 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,
Email: email, PreferredUsername: username,
EmailVerified: emailVerified, Email: email,
ConnectorData: connData, EmailVerified: emailVerified,
ConnectorData: connData,
} }
if c.userIDKey != "" { if c.userIDKey != "" {

View File

@ -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)
}) })