Merge pull request #1433 from jacksontj/userinfo

Add option in oidc to hit the optional userinfo endpoint
This commit is contained in:
Eric Chiang 2019-05-23 09:42:13 -07:00 committed by GitHub
commit 59560c9919
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 0 deletions

View File

@ -60,6 +60,12 @@ connectors:
# or if they are acting as a proxy for another IDP etc AWS Cognito with an upstream SAML IDP # 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 # This can be overridden with the below option
# insecureSkipEmailVerified: true # insecureSkipEmailVerified: true
# When enabled, the OpenID Connector will query the UserInfo endpoint for additional claims. UserInfo claims
# take priority over claims returned by the IDToken. This option should be used when the IDToken doesn't contain
# all the claims requested.
# https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
# getUserInfo: true
``` ```
[oidc-doc]: openid-connect.md [oidc-doc]: openid-connect.md

View File

@ -39,6 +39,11 @@ type Config struct {
// Override the value of email_verifed to true in the returned claims // Override the value of email_verifed to true in the returned claims
InsecureSkipEmailVerified bool `json:"insecureSkipEmailVerified"` InsecureSkipEmailVerified bool `json:"insecureSkipEmailVerified"`
// GetUserInfo uses the userinfo endpoint to get additional claims for
// the token. This is especially useful where upstreams return "thin"
// id tokens
GetUserInfo bool `json:"getUserInfo"`
} }
// Domains that don't support basic auth. golang.org/x/oauth2 has an internal // Domains that don't support basic auth. golang.org/x/oauth2 has an internal
@ -105,6 +110,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
clientID := c.ClientID clientID := c.ClientID
return &oidcConnector{ return &oidcConnector{
provider: provider,
redirectURI: c.RedirectURI, redirectURI: c.RedirectURI,
oauth2Config: &oauth2.Config{ oauth2Config: &oauth2.Config{
ClientID: clientID, ClientID: clientID,
@ -120,6 +126,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
cancel: cancel, cancel: cancel,
hostedDomains: c.HostedDomains, hostedDomains: c.HostedDomains,
insecureSkipEmailVerified: c.InsecureSkipEmailVerified, insecureSkipEmailVerified: c.InsecureSkipEmailVerified,
getUserInfo: c.GetUserInfo,
}, nil }, nil
} }
@ -129,6 +136,7 @@ var (
) )
type oidcConnector struct { type oidcConnector struct {
provider *oidc.Provider
redirectURI string redirectURI string
oauth2Config *oauth2.Config oauth2Config *oauth2.Config
verifier *oidc.IDTokenVerifier verifier *oidc.IDTokenVerifier
@ -137,6 +145,7 @@ type oidcConnector struct {
logger log.Logger logger log.Logger
hostedDomains []string hostedDomains []string
insecureSkipEmailVerified bool insecureSkipEmailVerified bool
getUserInfo bool
} }
func (c *oidcConnector) Close() error { func (c *oidcConnector) Close() error {
@ -219,6 +228,16 @@ func (c *oidcConnector) HandleCallback(s connector.Scopes, r *http.Request) (ide
} }
if c.getUserInfo {
userInfo, err := c.provider.UserInfo(r.Context(), oauth2.StaticTokenSource(token))
if err != nil {
return identity, fmt.Errorf("oidc: error loading userinfo: %v", err)
}
if err := userInfo.Claims(&claims); err != nil {
return identity, fmt.Errorf("oidc: failed to decode userinfo claims: %v", err)
}
}
identity = connector.Identity{ identity = connector.Identity{
UserID: idToken.Subject, UserID: idToken.Subject,
Username: claims.Username, Username: claims.Username,