diff --git a/conf/defaults.ini b/conf/defaults.ini index d34fe005355..2a5884efc9e 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -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 diff --git a/conf/sample.ini b/conf/sample.ini index 81944f1459a..f509496244d 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -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 diff --git a/docs/sources/setup-grafana/configure-grafana/_index.md b/docs/sources/setup-grafana/configure-grafana/_index.md index a322095cbcd..8c003a68e36 100644 --- a/docs/sources/setup-grafana/configure-grafana/_index.md +++ b/docs/sources/setup-grafana/configure-grafana/_index.md @@ -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`. diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/_index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/_index.md index 29d19121c45..158c51117d1 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/_index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/_index.md @@ -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 diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md index c3243a11409..206a641ad6f 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md @@ -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 diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md index fd28871a764..91252194de5 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md @@ -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_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 = client_secret = client_secret = scopes = openid email name diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/github/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/github/index.md index ae924a42296..9146e224623 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/github/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/github/index.md @@ -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. diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md index c15151b064f..333e190083f 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md @@ -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. diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md index 8194eb0efd9..31344b83f5b 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md @@ -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`. diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/grafana-com/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/grafana-com/index.md index f53c3448ce2..bfa992767fc 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/grafana-com/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/grafana-com/index.md @@ -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. diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/grafana/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/grafana/index.md index 98ff8f8947f..6fa8b003fdc 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/grafana/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/grafana/index.md @@ -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 diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md index 82aab5f70cd..c8e9aa21748 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md @@ -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" diff --git a/pkg/api/login.go b/pkg/api/login.go index 74d76373081..c2d81a77636 100644 --- a/pkg/api/login.go +++ b/pkg/api/login.go @@ -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") + + 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 - } else if len(oauthInfos) == 0 { - c.Logger.Warn("Skipping OAuth auto login because no OAuth providers are configured") + } + if autoLoginProvidersLen == 0 && setting.OAuthAutoLogin { + c.Logger.Warn("Skipping auto login because no auth providers are configured") return false } - for key := range oauthInfos { - redirectUrl := hs.Cfg.AppSubURL + "/login/" + key - c.Logger.Info("OAuth auto login enabled. Redirecting to " + redirectUrl) + + 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) { diff --git a/pkg/login/social/social.go b/pkg/login/social/social.go index 056457a8238..bc3f68eaea1 100644 --- a/pkg/login/social/social.go +++ b/pkg/login/social/social.go @@ -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 diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index ce242d71ed3..a52e745c7aa 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -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)