Commit eb0c3127 authored by Moto Ishizawa's avatar Moto Ishizawa

connector: add emailClaim setting to OIDC Connector

Add emailCiam setting to OIDC Connector for supporting an ID token
that does not contain the email claim.
parent 882ced42
......@@ -48,6 +48,7 @@ This connector config lets users authenticate with other OIDC providers. In addi
* clientID: a `string`. The OIDC client ID.
* clientSecret: a `string`. The OIDC client secret.
* trustedEmailProvider: a `boolean`. If true dex will trust the email address claims from this provider and not require that users verify their emails.
* emailClaim: a `string`. The name of the claim to be treated as an email claim. If empty dex will use a `email` claim.
In order to use the `oidc` connector you must register dex as an OIDC client; this mechanism is different from provider to provider. For Google, follow the instructions at their [developer site](https://developers.google.com/identity/protocols/OpenIDConnect?hl=en). Regardless of your provider, registering your client will also provide you with the client ID and secret.
......
......@@ -15,6 +15,7 @@ import (
const (
OIDCConnectorType = "oidc"
httpPathCallback = "/callback"
defaultEmailClaim = "email"
)
func init() {
......@@ -27,6 +28,7 @@ type OIDCConnectorConfig struct {
ClientID string `json:"clientID"`
ClientSecret string `json:"clientSecret"`
TrustedEmailProvider bool `json:"trustedEmailProvider"`
EmailClaim string `json:"emailClaim"`
}
func (cfg *OIDCConnectorConfig) ConnectorID() string {
......@@ -44,6 +46,7 @@ type OIDCConnector struct {
loginFunc oidc.LoginFunc
client *oidc.Client
trustedEmailProvider bool
emailClaim string
}
func (cfg *OIDCConnectorConfig) Connector(ns url.URL, lf oidc.LoginFunc, tpls *template.Template) (Connector, error) {
......@@ -69,6 +72,7 @@ func (cfg *OIDCConnectorConfig) Connector(ns url.URL, lf oidc.LoginFunc, tpls *t
loginFunc: lf,
client: cl,
trustedEmailProvider: cfg.TrustedEmailProvider,
emailClaim: cfg.EmailClaim,
}
return idpc, nil
}
......@@ -144,6 +148,30 @@ func (c *OIDCConnector) handleCallbackFunc(lf oidc.LoginFunc, errorURL url.URL)
return
}
// Override the email claim by using the value of the specified claim.
// This is used for the provider (e.g., Azure AD) which returns
// the ID token that does not include a email claim.
if c.emailClaim != "" && c.emailClaim != defaultEmailClaim {
email, ok, err := claims.StringClaim(c.emailClaim)
if err != nil {
log.Errorf("Unable to get value of alternative email claim: %v", err)
q.Set("error", oauth2.ErrorUnsupportedResponseType)
q.Set("error_description", "unable to get value of alternative email claim")
redirectError(w, errorURL, q)
return
}
if !ok {
log.Errorf("Failed parsing alternative email claim from remote provider: %v", err)
q.Set("error", oauth2.ErrorUnsupportedResponseType)
q.Set("error_description", "failed parsing alternative email claim")
redirectError(w, errorURL, q)
return
}
claims.Add(defaultEmailClaim, email)
}
ident, err := oidc.IdentityFromClaims(claims)
if err != nil {
log.Errorf("Failed parsing claims from remote provider: %v", err)
......
......@@ -337,6 +337,7 @@ func TestConnectors(t *testing.T) {
"clientID": "foo",
"clientSecret": "bar",
"trustedEmailProvider": true,
"emailClaim": "",
},
},
},
......@@ -353,6 +354,7 @@ func TestConnectors(t *testing.T) {
"clientID": "foo",
"clientSecret": "bar",
"trustedEmailProvider": true,
"emailClaim": "",
},
},
},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment