From c1d566bad4c13ec8a96ebe5bf78e1d6ee782fb34 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 9 Aug 2025 00:46:14 +0400 Subject: [PATCH] enh: oauth_sub_claim --- backend/open_webui/config.py | 23 +++++++++++++++++++++-- backend/open_webui/utils/oauth.py | 11 ++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 220e1e5018..8126dc30b1 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -168,9 +168,19 @@ class PersistentConfig(Generic[T]): self.config_path = config_path self.env_value = env_value self.config_value = get_config_value(config_path) + if self.config_value is not None and ENABLE_PERSISTENT_CONFIG: - log.info(f"'{env_name}' loaded from the latest database entry") - self.value = self.config_value + if ( + self.config_path.startswith("oauth.") + and not ENABLE_OAUTH_PERSISTENT_CONFIG + ): + log.info( + f"Skipping loading of '{env_name}' as OAuth persistent config is disabled" + ) + self.value = env_value + else: + log.info(f"'{env_name}' loaded from the latest database entry") + self.value = self.config_value else: self.value = env_value @@ -302,6 +312,9 @@ JWT_EXPIRES_IN = PersistentConfig( # OAuth config #################################### +ENABLE_OAUTH_PERSISTENT_CONFIG = ( + os.environ.get("ENABLE_OAUTH_PERSISTENT_CONFIG", "True").lower() == "true" +) ENABLE_OAUTH_SIGNUP = PersistentConfig( "ENABLE_OAUTH_SIGNUP", @@ -469,6 +482,12 @@ OAUTH_PROVIDER_NAME = PersistentConfig( os.environ.get("OAUTH_PROVIDER_NAME", "SSO"), ) +OAUTH_SUB_CLAIM = PersistentConfig( + "OAUTH_SUB_CLAIM", + "oauth.oidc.sub_claim", + os.environ.get("OAUTH_SUB_CLAIM", None), +) + OAUTH_USERNAME_CLAIM = PersistentConfig( "OAUTH_USERNAME_CLAIM", "oauth.oidc.username_claim", diff --git a/backend/open_webui/utils/oauth.py b/backend/open_webui/utils/oauth.py index 5776b85568..131c35800e 100644 --- a/backend/open_webui/utils/oauth.py +++ b/backend/open_webui/utils/oauth.py @@ -27,6 +27,7 @@ from open_webui.config import ( ENABLE_OAUTH_GROUP_CREATION, OAUTH_BLOCKED_GROUPS, OAUTH_ROLES_CLAIM, + OAUTH_SUB_CLAIM, OAUTH_GROUPS_CLAIM, OAUTH_EMAIL_CLAIM, OAUTH_PICTURE_CLAIM, @@ -65,6 +66,7 @@ auth_manager_config.ENABLE_OAUTH_GROUP_MANAGEMENT = ENABLE_OAUTH_GROUP_MANAGEMEN auth_manager_config.ENABLE_OAUTH_GROUP_CREATION = ENABLE_OAUTH_GROUP_CREATION auth_manager_config.OAUTH_BLOCKED_GROUPS = OAUTH_BLOCKED_GROUPS auth_manager_config.OAUTH_ROLES_CLAIM = OAUTH_ROLES_CLAIM +auth_manager_config.OAUTH_SUB_CLAIM = OAUTH_SUB_CLAIM auth_manager_config.OAUTH_GROUPS_CLAIM = OAUTH_GROUPS_CLAIM auth_manager_config.OAUTH_EMAIL_CLAIM = OAUTH_EMAIL_CLAIM auth_manager_config.OAUTH_PICTURE_CLAIM = OAUTH_PICTURE_CLAIM @@ -359,11 +361,18 @@ class OAuthManager: log.warning(f"OAuth callback failed, user data is missing: {token}") raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) - sub = user_data.get(OAUTH_PROVIDERS[provider].get("sub_claim", "sub")) + if auth_manager_config.OAUTH_SUB_CLAIM: + sub = user_data.get(auth_manager_config.OAUTH_SUB_CLAIM) + else: + # Fallback to the default sub claim if not configured + sub = user_data.get(OAUTH_PROVIDERS[provider].get("sub_claim", "sub")) + if not sub: log.warning(f"OAuth callback failed, sub is missing: {user_data}") raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) + provider_sub = f"{provider}@{sub}" + email_claim = auth_manager_config.OAUTH_EMAIL_CLAIM email = user_data.get(email_claim, "") # We currently mandate that email addresses are provided