From 4581a82ac46a2430bfc56480e8e12abb9b05ac4a Mon Sep 17 00:00:00 2001 From: colin-stuart Date: Thu, 9 Jan 2025 11:44:16 -0500 Subject: [PATCH] Auth: disable passwordless auth if any SAML/OAuth is enabled (#98227) * Auth: disable passwordless auth if any SAML/OAuth is enabled * Update pkg/services/authn/authnimpl/registration.go Co-authored-by: Victor Cinaglia * simplify check if any auth providers are enabled * add accidentally removed break statement, use IsEnabled with empty context to check if PasswordlessMagicLinkAuth enabled * use IsClientEnabled * Update pkg/api/frontendsettings.go Co-authored-by: Misi --------- Co-authored-by: Victor Cinaglia Co-authored-by: Misi --- pkg/api/frontendsettings.go | 20 ++++++++++++++++- pkg/services/authn/authn.go | 1 + pkg/services/authn/authnimpl/registration.go | 23 +++++++++++++++++--- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/pkg/api/frontendsettings.go b/pkg/api/frontendsettings.go index 2d45da7017d..61e29c977be 100644 --- a/pkg/api/frontendsettings.go +++ b/pkg/api/frontendsettings.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/login/social" "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/services/accesscontrol" + "github.com/grafana/grafana/pkg/services/authn" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -360,7 +361,24 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro OktaSkipOrgRoleSync: parseSkipOrgRoleSyncEnabled(oauthProviders[social.OktaProviderName]), DisableLogin: hs.Cfg.DisableLogin, BasicAuthStrongPasswordPolicy: hs.Cfg.BasicAuthStrongPasswordPolicy, - PasswordlessEnabled: hs.Cfg.PasswordlessMagicLinkAuth.Enabled && hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagPasswordlessMagicLinkAuthentication), + } + + if hs.Cfg.PasswordlessMagicLinkAuth.Enabled && hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagPasswordlessMagicLinkAuthentication) { + hasEnabledProviders := hs.samlEnabled() || hs.authnService.IsClientEnabled(authn.ClientLDAP) + + if !hasEnabledProviders { + oauthInfos := hs.SocialService.GetOAuthInfoProviders() + for _, provider := range oauthInfos { + if provider.Enabled { + hasEnabledProviders = true + break + } + } + } + + if !hasEnabledProviders { + frontendSettings.Auth.PasswordlessEnabled = true + } } if hs.pluginsCDNService != nil && hs.pluginsCDNService.IsEnabled() { diff --git a/pkg/services/authn/authn.go b/pkg/services/authn/authn.go index 07d019e528e..8ae12fc0de9 100644 --- a/pkg/services/authn/authn.go +++ b/pkg/services/authn/authn.go @@ -30,6 +30,7 @@ const ( ClientProxy = "auth.client.proxy" ClientSAML = "auth.client.saml" ClientPasswordless = "auth.client.passwordless" + ClientLDAP = "ldap" ) const ( diff --git a/pkg/services/authn/authnimpl/registration.go b/pkg/services/authn/authnimpl/registration.go index b73c051c2a1..04e074040aa 100644 --- a/pkg/services/authn/authnimpl/registration.go +++ b/pkg/services/authn/authnimpl/registration.go @@ -1,6 +1,8 @@ package authnimpl import ( + "context" + "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/remotecache" "github.com/grafana/grafana/pkg/infra/tracing" @@ -80,9 +82,24 @@ func ProvideRegistration( } } - if cfg.PasswordlessMagicLinkAuth.Enabled && features.IsEnabledGlobally(featuremgmt.FlagPasswordlessMagicLinkAuthentication) { - passwordless := clients.ProvidePasswordless(cfg, loginAttempts, userService, tempUserService, notificationService, cache) - authnSvc.RegisterClient(passwordless) + if cfg.PasswordlessMagicLinkAuth.Enabled && features.IsEnabled(context.Background(), featuremgmt.FlagPasswordlessMagicLinkAuthentication) { + hasEnabledProviders := authnSvc.IsClientEnabled(authn.ClientSAML) || authnSvc.IsClientEnabled(authn.ClientLDAP) + if !hasEnabledProviders { + oauthInfos := socialService.GetOAuthInfoProviders() + for _, provider := range oauthInfos { + if provider.Enabled { + hasEnabledProviders = true + break + } + } + } + + if hasEnabledProviders { + logger.Error("Failed to configure passwordless magic link auth: cannot enable both passwordless magic link auth & SSO") + } else { + passwordless := clients.ProvidePasswordless(cfg, loginAttempts, userService, tempUserService, notificationService, cache) + authnSvc.RegisterClient(passwordless) + } } if cfg.AuthProxy.Enabled && len(proxyClients) > 0 {