From d64ef1803d2f5cedb7b3a308151d08ff2cd2b8e1 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Mon, 1 Jun 2026 13:07:49 -0700 Subject: [PATCH] refac Co-Authored-By: Zaid Marji <91486926+zaid-marji@users.noreply.github.com> --- backend/open_webui/config.py | 6 ++++++ backend/open_webui/main.py | 7 ++++++- src/lib/stores/index.ts | 1 + src/routes/auth/+page.svelte | 23 ++++++++++++++++++++++- 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index bec7052190..57f4712027 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -3448,6 +3448,12 @@ ENABLE_OAUTH_SIGNUP = ConfigVar( os.getenv('ENABLE_OAUTH_SIGNUP', 'False').lower() == 'true', ) +OAUTH_AUTO_REDIRECT = ConfigVar( + 'OAUTH_AUTO_REDIRECT', + 'oauth.auto_redirect', + os.getenv('OAUTH_AUTO_REDIRECT', 'False').lower() == 'true', +) + OAUTH_REFRESH_TOKEN_INCLUDE_SCOPE = ConfigVar( 'OAUTH_REFRESH_TOKEN_INCLUDE_SCOPE', 'oauth.refresh_token_include_scope', diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 7dc765a56c..12541ff66e 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -289,6 +289,7 @@ from open_webui.config import ( MOJEEK_SEARCH_API_KEY, OAUTH_ADMIN_ROLES, OAUTH_ALLOWED_ROLES, + OAUTH_AUTO_REDIRECT, OAUTH_EMAIL_CLAIM, OAUTH_PICTURE_CLAIM, OAUTH_PROVIDERS, @@ -864,6 +865,7 @@ app.state.BASE_MODELS = [] app.state.config.WEBUI_URL = WEBUI_URL app.state.config.ENABLE_SIGNUP = ENABLE_SIGNUP app.state.config.ENABLE_LOGIN_FORM = ENABLE_LOGIN_FORM +app.state.config.OAUTH_AUTO_REDIRECT = OAUTH_AUTO_REDIRECT app.state.config.ENABLE_PASSWORD_CHANGE_FORM = ENABLE_PASSWORD_CHANGE_FORM app.state.config.ENABLE_API_KEYS = ENABLE_API_KEYS @@ -2357,7 +2359,10 @@ async def get_app_config(request: Request): 'name': app.state.WEBUI_NAME, 'version': VERSION, 'default_locale': str(DEFAULT_LOCALE), - 'oauth': {'providers': {name: config.get('name', name) for name, config in OAUTH_PROVIDERS.items()}}, + 'oauth': { + 'providers': {name: config.get('name', name) for name, config in OAUTH_PROVIDERS.items()}, + 'auto_redirect': app.state.config.OAUTH_AUTO_REDIRECT, + }, 'features': { # --- Public: required by login/signup page pre-auth --- 'auth': WEBUI_AUTH, diff --git a/src/lib/stores/index.ts b/src/lib/stores/index.ts index de18dfaa96..b87303c0b0 100644 --- a/src/lib/stores/index.ts +++ b/src/lib/stores/index.ts @@ -307,6 +307,7 @@ type Config = { providers: { [key: string]: string; }; + auto_redirect?: boolean; }; ui?: { pending_user_overlay_title?: string; diff --git a/src/routes/auth/+page.svelte b/src/routes/auth/+page.svelte index b11f85b7a5..e1bae7c3b7 100644 --- a/src/routes/auth/+page.svelte +++ b/src/routes/auth/+page.svelte @@ -183,10 +183,31 @@ await oauthCallbackHandler(); form = $page.url.searchParams.get('form'); + // Auto-redirect to SSO when OAUTH_AUTO_REDIRECT is enabled and the + // deployment is unambiguously SSO-only (single provider, no login form, + // no LDAP). Suppressed by ?form=, ?error=, onboarding, trusted-header + // auth, or an existing session/token. + if ($config?.oauth?.auto_redirect && !form && !error) { + const providers = Object.keys($config?.oauth?.providers ?? {}); + if ( + providers.length === 1 && + $config?.features?.auth !== false && + $config?.features?.enable_login_form === false && + !$config?.features?.enable_ldap && + !$config?.features?.auth_trusted_header && + !$config?.onboarding && + !localStorage.token && + !document.cookie.split('; ').some((c) => c.startsWith('token=')) + ) { + window.location.href = `${WEBUI_BASE_URL}/oauth/${providers[0]}/login`; + return; + } + } + loaded = true; setLogoImage(); - if (($config?.features.auth_trusted_header ?? false) || $config?.features.auth === false) { + if (($config?.features?.auth_trusted_header ?? false) || $config?.features?.auth === false) { await signInHandler(); } else { onboarding = $config?.onboarding ?? false;