Commit f257ff02 by Bob Shannon Committed by Torkel Ödegaard

Allow oauth email attribute name to be configurable (#13006)

* Allow oauth email attribute name to be configurable

Signed-off-by: Bob Shannon <bshannon@palantir.com>

* Document e-mail determination steps for generic oauth

* Add reference to email_attribute_name

* Re-add e-mail determination docs to new generic-oauth page

* Inherit default e-mail attribute from defaults.ini
parent 7c78b64a
...@@ -321,6 +321,7 @@ allow_sign_up = true ...@@ -321,6 +321,7 @@ allow_sign_up = true
client_id = some_id client_id = some_id
client_secret = some_secret client_secret = some_secret
scopes = user:email scopes = user:email
email_attribute_name = email:primary
auth_url = auth_url =
token_url = token_url =
api_url = api_url =
......
...@@ -32,7 +32,14 @@ allowed_domains = mycompany.com mycompany.org ...@@ -32,7 +32,14 @@ allowed_domains = mycompany.com mycompany.org
allow_sign_up = true allow_sign_up = true
``` ```
Set api_url to the resource that returns [OpenID UserInfo](https://connect2id.com/products/server/docs/api/userinfo) compatible information. Set `api_url` to the resource that returns [OpenID UserInfo](https://connect2id.com/products/server/docs/api/userinfo) compatible information.
Grafana will attempt to determine the user's e-mail address by querying the OAuth provider as described below in the following order until an e-mail address is found:
1. Check for the presence of an e-mail address via the `email` field encoded in the OAuth `id_token` parameter.
2. Check for the presence of an e-mail address in the `attributes` map encoded in the OAuth `id_token` parameter. By default Grafana will perform a lookup into the attributes map using the `email:primary` key, however, this is configurable and can be adjusted by using the `email_attribute_name` configuration option.
3. Query the `/emails` endpoint of the OAuth provider's API (configured with `api_url`) and check for the presence of an e-mail address marked as a primary address.
4. If no e-mail address is found in steps (1-3), then the e-mail address of the user is set to the empty string.
## Set up OAuth2 with Okta ## Set up OAuth2 with Okta
......
...@@ -5,6 +5,7 @@ type OAuthInfo struct { ...@@ -5,6 +5,7 @@ type OAuthInfo struct {
Scopes []string Scopes []string
AuthUrl, TokenUrl string AuthUrl, TokenUrl string
Enabled bool Enabled bool
EmailAttributeName string
AllowedDomains []string AllowedDomains []string
HostedDomain string HostedDomain string
ApiUrl string ApiUrl string
......
...@@ -20,6 +20,7 @@ type SocialGenericOAuth struct { ...@@ -20,6 +20,7 @@ type SocialGenericOAuth struct {
allowedOrganizations []string allowedOrganizations []string
apiUrl string apiUrl string
allowSignup bool allowSignup bool
emailAttributeName string
teamIds []int teamIds []int
} }
...@@ -264,8 +265,9 @@ func (s *SocialGenericOAuth) extractEmail(data *UserInfoJson) string { ...@@ -264,8 +265,9 @@ func (s *SocialGenericOAuth) extractEmail(data *UserInfoJson) string {
return data.Email return data.Email
} }
if data.Attributes["email:primary"] != nil { emails, ok := data.Attributes[s.emailAttributeName]
return data.Attributes["email:primary"][0] if ok && len(emails) != 0 {
return emails[0]
} }
if data.Upn != "" { if data.Upn != "" {
......
...@@ -67,6 +67,7 @@ func NewOAuthService() { ...@@ -67,6 +67,7 @@ func NewOAuthService() {
TokenUrl: sec.Key("token_url").String(), TokenUrl: sec.Key("token_url").String(),
ApiUrl: sec.Key("api_url").String(), ApiUrl: sec.Key("api_url").String(),
Enabled: sec.Key("enabled").MustBool(), Enabled: sec.Key("enabled").MustBool(),
EmailAttributeName: sec.Key("email_attribute_name").String(),
AllowedDomains: util.SplitString(sec.Key("allowed_domains").String()), AllowedDomains: util.SplitString(sec.Key("allowed_domains").String()),
HostedDomain: sec.Key("hosted_domain").String(), HostedDomain: sec.Key("hosted_domain").String(),
AllowSignup: sec.Key("allow_sign_up").MustBool(), AllowSignup: sec.Key("allow_sign_up").MustBool(),
...@@ -153,6 +154,7 @@ func NewOAuthService() { ...@@ -153,6 +154,7 @@ func NewOAuthService() {
allowedDomains: info.AllowedDomains, allowedDomains: info.AllowedDomains,
apiUrl: info.ApiUrl, apiUrl: info.ApiUrl,
allowSignup: info.AllowSignup, allowSignup: info.AllowSignup,
emailAttributeName: info.EmailAttributeName,
teamIds: sec.Key("team_ids").Ints(","), teamIds: sec.Key("team_ids").Ints(","),
allowedOrganizations: util.SplitString(sec.Key("allowed_organizations").String()), allowedOrganizations: util.SplitString(sec.Key("allowed_organizations").String()),
} }
......
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