SAML: Support auto login (#61685)

* SAML: Support auto login

* Add individual auto_login option for each OAuth provider

* Docs: Describe new auto_login option

* Minor refactor
This commit is contained in:
Alexander Zobnin 2023-01-19 15:53:02 +01:00 committed by GitHub
parent 06350ed887
commit 60ef88c918
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 160 additions and 26 deletions

View File

@ -477,6 +477,7 @@ signout_redirect_url =
# Set to true to attempt login with OAuth automatically, skipping the login screen.
# This setting is ignored if multiple OAuth providers are configured.
# Deprecated, use auto_login option for specific provider instead.
oauth_auto_login = false
# OAuth state max age cookie duration in seconds. Defaults to 600 seconds.
@ -515,6 +516,7 @@ hide_version = false
[auth.github]
enabled = false
allow_sign_up = true
auto_login = false
client_id = some_id
client_secret =
scopes = user:email,read:org
@ -532,6 +534,7 @@ allow_assign_grafana_admin = false
[auth.gitlab]
enabled = false
allow_sign_up = true
auto_login = false
client_id = some_id
client_secret =
scopes = api
@ -548,6 +551,7 @@ allow_assign_grafana_admin = false
[auth.google]
enabled = false
allow_sign_up = true
auto_login = false
client_id = some_client_id
client_secret =
scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
@ -571,6 +575,7 @@ allowed_organizations =
[auth.grafana_com]
enabled = false
allow_sign_up = true
auto_login = false
client_id = some_id
client_secret =
scopes = user:email
@ -582,6 +587,7 @@ skip_org_role_sync = false
name = Azure AD
enabled = false
allow_sign_up = true
auto_login = false
client_id = some_client_id
client_secret =
scopes = openid email profile
@ -599,6 +605,7 @@ name = Okta
icon = okta
enabled = false
allow_sign_up = true
auto_login = false
client_id = some_id
client_secret =
scopes = openid profile email groups
@ -617,6 +624,7 @@ name = OAuth
icon = signin
enabled = false
allow_sign_up = true
auto_login = false
client_id = some_id
client_secret =
scopes = user:email

View File

@ -478,6 +478,7 @@
# Set to true to attempt login with OAuth automatically, skipping the login screen.
# This setting is ignored if multiple OAuth providers are configured.
# Deprecated, use auto_login option for specific provider instead.
;oauth_auto_login = false
# OAuth state max age cookie duration in seconds. Defaults to 600 seconds.
@ -519,6 +520,7 @@
[auth.github]
;enabled = false
;allow_sign_up = true
;auto_login = false
;client_id = some_id
;client_secret = some_secret
;scopes = user:email,read:org
@ -536,6 +538,7 @@
[auth.gitlab]
;enabled = false
;allow_sign_up = true
;auto_login = false
;client_id = some_id
;client_secret = some_secret
;scopes = api
@ -552,6 +555,7 @@
[auth.google]
;enabled = false
;allow_sign_up = true
;auto_login = false
;client_id = some_client_id
;client_secret = some_client_secret
;scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
@ -566,6 +570,7 @@
[auth.grafana_com]
;enabled = false
;allow_sign_up = true
;auto_login = false
;client_id = some_id
;client_secret = some_secret
;scopes = user:email
@ -577,6 +582,7 @@
;name = Azure AD
;enabled = false
;allow_sign_up = true
;auto_login = false
;client_id = some_client_id
;client_secret = some_client_secret
;scopes = openid email profile
@ -594,6 +600,7 @@
;name = Okta
;enabled = false
;allow_sign_up = true
;auto_login = false
;client_id = some_id
;client_secret = some_secret
;scopes = openid profile email groups
@ -611,6 +618,7 @@
;enabled = false
;name = OAuth
;allow_sign_up = true
;auto_login = false
;client_id = some_id
;client_secret = some_secret
;scopes = user:email,read:org

View File

@ -839,6 +839,8 @@ URL to redirect the user to after they sign out.
### oauth_auto_login
> **Note**: This option is deprecated - use `auto_login` option for specific OAuth provider instead.
Set to `true` to attempt login with OAuth automatically, skipping the login screen.
This setting is ignored if multiple OAuth providers are configured. Default is `false`.

View File

@ -116,13 +116,13 @@ disable_login_form = true
### Automatic OAuth login
Set to true to attempt login with OAuth automatically, skipping the login screen.
This setting is ignored if multiple OAuth providers are configured.
Set to true to attempt login with specific OAuth provider automatically, skipping the login screen.
This setting is ignored if multiple auth providers are configured to use auto login.
Defaults to `false`.
```bash
[auth]
oauth_auto_login = true
[auth.generic_oauth]
auto_login = true
```
### Avoid automatic OAuth login

View File

@ -132,6 +132,7 @@ If the setting is set to `false`, the user is assigned the role of `Admin` of th
name = Azure AD
enabled = true
allow_sign_up = true
auto_login = false
client_id = APPLICATION_ID
client_secret = CLIENT_SECRET
scopes = openid email profile
@ -190,6 +191,15 @@ The `allowed_domains` option limits access to users who belong to specific domai
allowed_domains = mycompany.com mycompany.org
```
### Configure automatic login
Set `auto_login` option to true to attempt login automatically, skipping the login screen.
This setting is ignored if multiple auth providers are configured to use auto login.
```
auto_login = true
```
### Team Sync (Enterprise only)
With Team Sync you can map your Azure AD groups to teams in Grafana so that your users will automatically be added to

View File

@ -35,6 +35,8 @@ Example config:
name = OAuth
icon = signin
enabled = true
allow_sign_up = true
auto_login = false
client_id = YOUR_APP_CLIENT_ID
client_secret = YOUR_APP_CLIENT_SECRET
scopes =
@ -43,7 +45,6 @@ auth_url =
token_url =
api_url =
allowed_domains = mycompany.com mycompany.org
allow_sign_up = true
tls_skip_verify_insecure = false
tls_client_cert =
tls_client_key =
@ -130,6 +131,15 @@ To configure Generic OAuth to use a refresh token, perform one or both of the fo
- Extend the `[auth.generic_oauth]` section with additional scopes
- Enable the refresh token on the provider
### Configure automatic login
Set `auto_login` option to true to attempt login automatically, skipping the login screen.
This setting is ignored if multiple auth providers are configured to use auto login.
```
auto_login = true
```
## Set up OAuth2 with Auth0
1. Use the following parameters to create a client in Auth0:
@ -147,6 +157,7 @@ To configure Generic OAuth to use a refresh token, perform one or both of the fo
[auth.generic_oauth]
enabled = true
allow_sign_up = true
auto_login = false
team_ids =
allowed_organizations =
name = Auth0
@ -166,6 +177,7 @@ To configure Generic OAuth to use a refresh token, perform one or both of the fo
name = BitBucket
enabled = true
allow_sign_up = true
auto_login = false
client_id = <client id>
client_secret = <client secret>
scopes = account email
@ -203,6 +215,7 @@ By default, a refresh token is included in the response for the **Authorization
name = Centrify
enabled = true
allow_sign_up = true
auto_login = false
client_id = <OpenID Connect Client ID from Centrify>
client_secret = <your generated OpenID Connect Client Secret"
scopes = openid profile email
@ -242,6 +255,7 @@ By default, a refresh token is included in the response for the **Authorization
name = OneLogin
enabled = true
allow_sign_up = true
auto_login = false
client_id = <client id>
client_secret = <client secret>
scopes = openid email name

View File

@ -39,6 +39,7 @@ example:
[auth.github]
enabled = true
allow_sign_up = true
auto_login = false
client_id = YOUR_GITHUB_APP_CLIENT_ID
client_secret = YOUR_GITHUB_APP_CLIENT_SECRET
scopes = user:email,read:org
@ -81,6 +82,8 @@ Grafana instance. For example:
```bash
[auth.github]
enabled = true
allow_sign_up = true
auto_login = false
client_id = YOUR_GITHUB_APP_CLIENT_ID
client_secret = YOUR_GITHUB_APP_CLIENT_SECRET
scopes = user:email,read:org
@ -88,7 +91,6 @@ team_ids = 150,300
auth_url = https://github.com/login/oauth/authorize
token_url = https://github.com/login/oauth/access_token
api_url = https://api.github.com/user
allow_sign_up = true
```
### allowed_organizations
@ -101,17 +103,27 @@ your Grafana instance. For example
```bash
[auth.github]
enabled = true
allow_sign_up = true
auto_login = false
client_id = YOUR_GITHUB_APP_CLIENT_ID
client_secret = YOUR_GITHUB_APP_CLIENT_SECRET
scopes = user:email,read:org
auth_url = https://github.com/login/oauth/authorize
token_url = https://github.com/login/oauth/access_token
api_url = https://api.github.com/user
allow_sign_up = true
# space-delimited organization names
allowed_organizations = github google
```
### Configure automatic login
Set `auto_login` option to true to attempt login automatically, skipping the login screen.
This setting is ignored if multiple auth providers are configured to use auto login.
```
auto_login = true
```
### Map roles
You can use GitHub OAuth to map roles. During mapping, Grafana checks for the presence of a role using the [JMESPath](http://jmespath.org/examples.html) specified via the `role_attribute_path` configuration option.

View File

@ -49,7 +49,8 @@ authentication:
```bash
[auth.gitlab]
enabled = true
allow_sign_up = false
allow_sign_up = true
auto_login = false
client_id = GITLAB_APPLICATION_ID
client_secret = GITLAB_SECRET
scopes = read_api
@ -128,6 +129,7 @@ the `example` and `foo/bar` groups. The example also promotes all GitLab Admins
[auth.gitlab]
enabled = true
allow_sign_up = true
auto_login = false
client_id = GITLAB_APPLICATION_ID
client_secret = GITLAB_SECRET
scopes = read_api
@ -140,6 +142,15 @@ role_attribute_strict = true
allow_assign_grafana_admin = false
```
### Configure automatic login
Set `auto_login` option to true to attempt login automatically, skipping the login screen.
This setting is ignored if multiple auth providers are configured to use auto login.
```
auto_login = true
```
### Map roles
You can use GitLab OAuth to map roles. During mapping, Grafana checks for the presence of a role using the [JMESPath](http://jmespath.org/examples.html) specified via the `role_attribute_path` configuration option.

View File

@ -32,13 +32,14 @@ Specify the Client ID and Secret in the [Grafana configuration file]({{< relref
```bash
[auth.google]
enabled = true
allow_sign_up = true
auto_login = false
client_id = CLIENT_ID
client_secret = CLIENT_SECRET
scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
auth_url = https://accounts.google.com/o/oauth2/auth
token_url = https://accounts.google.com/o/oauth2/token
allowed_domains = mycompany.com mycompany.org
allow_sign_up = true
hosted_domain = mycompany.com
```
@ -69,6 +70,15 @@ Grafana uses a refresh token to obtain a new access token without requiring the
By default, Grafana includes the `access_type=offline` parameter in the authorization request to request a refresh token.
### Configure automatic login
Set `auto_login` option to true to attempt login automatically, skipping the login screen.
This setting is ignored if multiple auth providers are configured to use auto login.
```
auto_login = true
```
## Skip organization role sync
We do not currently sync roles from Google and instead set the AutoAssigned role to the user at first login. To manage your user's organization role from within Grafana, set `skip_org_role_sync` to `true`.

View File

@ -27,6 +27,7 @@ The following snippet shows an example configuration:
[auth.grafana_com]
enabled = true
allow_sign_up = true
auto_login = false
client_id = 450bc21c10dc2194879d
client_secret = eyJ0Ijoib2F1dGgyYyIhlmlkIjoiNzUwYmMzM2MxMGRjMjE6NDh3OWQiLCJ2IjoiZmI1YzVlYmIwYzFmN2ZhYzZmNjIwOGI1NmVkYTRlNWYxMzgwM2NkMiJ9
scopes = user:email
@ -34,6 +35,15 @@ allowed_organizations = sampleorganization
enabled = true
```
### Configure automatic login
Set `auto_login` option to true to attempt login automatically, skipping the login screen.
This setting is ignored if multiple auth providers are configured to use auto login.
```
auto_login = true
```
## Skip organization role sync
To prevent the sync of org roles from Grafana.com, set `skip_org_role_sync` to `true`. This is useful if you want to manage the organization roles for your users from within Grafana.

View File

@ -96,13 +96,13 @@ disable_login_form = true
### Automatic OAuth login
Set to true to attempt login with OAuth automatically, skipping the login screen.
This setting is ignored if multiple OAuth providers are configured.
Set to true to attempt login with specific OAuth provider automatically, skipping the login screen.
This setting is ignored if multiple auth providers are configured to use auto login.
Defaults to `false`.
```bash
[auth]
oauth_auto_login = true
[auth.generic_oauth]
auto_login = true
```
### Hide sign-out menu

View File

@ -67,6 +67,7 @@ root_url = https://grafana.example.com
[auth.saml]
enabled = true
auto_login = false
private_key_path = "/path/to/private_key.pem"
certificate_path = "/path/to/certificate.cert"
idp_metadata_url = "https://my-org.okta.com/app/my-application/sso/saml/metadata"
@ -169,6 +170,7 @@ The table below describes all SAML configuration options. Continue reading below
| `enabled` | No | Whether SAML authentication is allowed | `false` |
| `single_logout` | No | Whether SAML Single Logout enabled | `false` |
| `allow_sign_up` | No | Whether to allow new Grafana user creation through SAML login. If set to `false`, then only existing Grafana users can log in with SAML. | `true` |
| `auto_login` | No | Whether SAML auto login is enabled | `false` |
| `allow_idp_initiated` | No | Whether SAML IdP-initiated login is allowed | `false` |
| `certificate` or `certificate_path` | Yes | Base64-encoded string or Path for the SP X.509 certificate | |
| `private_key` or `private_key_path` | Yes | Base64-encoded string or Path for the SP private key | |
@ -271,6 +273,15 @@ assertion_attribute_name = $__saml{firstName} $__saml{lastName}
By default, new Grafana users using SAML authentication will have an account created for them automatically. To decouple authentication and account creation and ensure only users with existing accounts can log in with SAML, set the `allow_sign_up` option to false.
### Configure automatic login
Set `auto_login` option to true to attempt login automatically, skipping the login screen.
This setting is ignored if multiple auth providers are configured to use auto login.
```
auto_login = true
```
### Configure team sync
> **Note:** Team sync support for SAML is available in Grafana version 7.0 and later.
@ -401,6 +412,7 @@ allowed_organizations = ["org 1", "second org"]
```bash
[auth.saml]
enabled = true
auto_login = false
certificate_path = "/path/to/certificate.cert"
private_key_path = "/path/to/private_key.pem"
idp_metadata_path = "/my/metadata.xml"

View File

@ -105,7 +105,7 @@ func (hs *HTTPServer) LoginView(c *models.ReqContext) {
return
}
if hs.tryOAuthAutoLogin(c) {
if hs.tryAutoLogin(c) {
return
}
@ -139,24 +139,49 @@ func (hs *HTTPServer) LoginView(c *models.ReqContext) {
c.HTML(http.StatusOK, getViewIndex(), viewData)
}
func (hs *HTTPServer) tryOAuthAutoLogin(c *models.ReqContext) bool {
if !setting.OAuthAutoLogin {
return false
}
func (hs *HTTPServer) tryAutoLogin(c *models.ReqContext) bool {
samlAutoLogin := hs.samlAutoLoginEnabled()
oauthInfos := hs.SocialService.GetOAuthInfoProviders()
if len(oauthInfos) > 1 {
c.Logger.Warn("Skipping OAuth auto login because multiple OAuth providers are configured")
return false
} else if len(oauthInfos) == 0 {
c.Logger.Warn("Skipping OAuth auto login because no OAuth providers are configured")
autoLoginProvidersLen := 0
for _, provider := range oauthInfos {
if provider.AutoLogin {
autoLoginProvidersLen++
}
}
// If no auto_login option configured for specific OAuth, use legacy option
if setting.OAuthAutoLogin && autoLoginProvidersLen == 0 {
autoLoginProvidersLen = len(oauthInfos)
}
if samlAutoLogin {
autoLoginProvidersLen++
}
if autoLoginProvidersLen > 1 {
c.Logger.Warn("Skipping auto login because multiple auth providers are configured with auto_login option")
return false
}
for key := range oauthInfos {
redirectUrl := hs.Cfg.AppSubURL + "/login/" + key
c.Logger.Info("OAuth auto login enabled. Redirecting to " + redirectUrl)
if autoLoginProvidersLen == 0 && setting.OAuthAutoLogin {
c.Logger.Warn("Skipping auto login because no auth providers are configured")
return false
}
for providerName, provider := range oauthInfos {
if provider.AutoLogin || setting.OAuthAutoLogin {
redirectUrl := hs.Cfg.AppSubURL + "/login/" + providerName
c.Logger.Info("OAuth auto login enabled. Redirecting to " + redirectUrl)
c.Redirect(redirectUrl, 307)
return true
}
}
if samlAutoLogin {
redirectUrl := hs.Cfg.AppSubURL + "/login/saml"
c.Logger.Info("SAML auto login enabled. Redirecting to " + redirectUrl)
c.Redirect(redirectUrl, 307)
return true
}
return false
}
@ -403,6 +428,10 @@ func (hs *HTTPServer) samlSingleLogoutEnabled() bool {
return hs.samlEnabled() && hs.SettingsProvider.KeyValue("auth.saml", "single_logout").MustBool(false) && hs.samlEnabled()
}
func (hs *HTTPServer) samlAutoLoginEnabled() bool {
return hs.samlEnabled() && hs.SettingsProvider.KeyValue("auth.saml", "auto_login").MustBool(false)
}
func getLoginExternalError(err error) string {
var createTokenErr *auth.CreateTokenErr
if errors.As(err, &createTokenErr) {

View File

@ -57,6 +57,7 @@ type OAuthInfo struct {
TlsClientCa string
TlsSkipVerify bool
UsePKCE bool
AutoLogin bool
}
func ProvideService(cfg *setting.Cfg, features *featuremgmt.FeatureManager) *SocialService {
@ -95,6 +96,7 @@ func ProvideService(cfg *setting.Cfg, features *featuremgmt.FeatureManager) *Soc
TlsSkipVerify: sec.Key("tls_skip_verify_insecure").MustBool(),
UsePKCE: sec.Key("use_pkce").MustBool(),
AllowAssignGrafanaAdmin: sec.Key("allow_assign_grafana_admin").MustBool(false),
AutoLogin: sec.Key("auto_login").MustBool(false),
}
// when empty_scopes parameter exists and is true, overwrite scope with empty value

View File

@ -1408,7 +1408,13 @@ func readAuthSettings(iniFile *ini.File, cfg *Cfg) (err error) {
DisableLoginForm = auth.Key("disable_login_form").MustBool(false)
DisableSignoutMenu = auth.Key("disable_signout_menu").MustBool(false)
// Deprecated
OAuthAutoLogin = auth.Key("oauth_auto_login").MustBool(false)
if OAuthAutoLogin {
cfg.Logger.Warn("[Deprecated] The oauth_auto_login configuration setting is deprecated. Please use auto_login inside auth provider section instead.")
}
cfg.OAuthCookieMaxAge = auth.Key("oauth_state_cookie_max_age").MustInt(600)
SignoutRedirectUrl = valueAsString(auth, "signout_redirect_url", "")
cfg.OAuthSkipOrgRoleUpdateSync = auth.Key("oauth_skip_org_role_update_sync").MustBool(false)