diff --git a/backend/open_webui/env.py b/backend/open_webui/env.py index 3d2cabdf18..cc5eff51df 100644 --- a/backend/open_webui/env.py +++ b/backend/open_webui/env.py @@ -983,6 +983,7 @@ FORWARD_USER_INFO_HEADER_USER_NAME = os.getenv('FORWARD_USER_INFO_HEADER_USER_NA FORWARD_USER_INFO_HEADER_USER_ID = os.getenv('FORWARD_USER_INFO_HEADER_USER_ID', 'X-OpenWebUI-User-Id') FORWARD_USER_INFO_HEADER_USER_EMAIL = os.getenv('FORWARD_USER_INFO_HEADER_USER_EMAIL', 'X-OpenWebUI-User-Email') FORWARD_USER_INFO_HEADER_USER_ROLE = os.getenv('FORWARD_USER_INFO_HEADER_USER_ROLE', 'X-OpenWebUI-User-Role') +FORWARD_USER_INFO_HEADER_AUTH_TYPE = os.getenv('FORWARD_USER_INFO_HEADER_AUTH_TYPE', 'X-OpenWebUI-Auth-Type') FORWARD_SESSION_INFO_HEADER_MESSAGE_ID = os.getenv('FORWARD_SESSION_INFO_HEADER_MESSAGE_ID', 'X-OpenWebUI-Message-Id') FORWARD_SESSION_INFO_HEADER_CHAT_ID = os.getenv('FORWARD_SESSION_INFO_HEADER_CHAT_ID', 'X-OpenWebUI-Chat-Id') diff --git a/backend/open_webui/routers/ollama.py b/backend/open_webui/routers/ollama.py index 125babfe16..23a43aaaa9 100644 --- a/backend/open_webui/routers/ollama.py +++ b/backend/open_webui/routers/ollama.py @@ -119,7 +119,7 @@ async def send_request( } if ENABLE_FORWARD_USER_INFO_HEADERS and user: - headers = include_user_info_headers(headers, user) + headers = include_user_info_headers(headers, user, request=request) if metadata and metadata.get('chat_id'): headers[FORWARD_SESSION_INFO_HEADER_CHAT_ID] = metadata.get('chat_id') diff --git a/backend/open_webui/routers/openai.py b/backend/open_webui/routers/openai.py index 925e6d41ec..c62b2f7194 100644 --- a/backend/open_webui/routers/openai.py +++ b/backend/open_webui/routers/openai.py @@ -103,7 +103,7 @@ async def send_get_request( cookies = None if ENABLE_FORWARD_USER_INFO_HEADERS and user: - headers = include_user_info_headers(headers, user) + headers = include_user_info_headers(headers, user, request=request) async with session.get( url, @@ -176,7 +176,7 @@ async def get_headers_and_cookies( } if ENABLE_FORWARD_USER_INFO_HEADERS and user: - headers = include_user_info_headers(headers, user) + headers = include_user_info_headers(headers, user, request=request) if metadata and metadata.get('chat_id'): headers[FORWARD_SESSION_INFO_HEADER_CHAT_ID] = metadata.get('chat_id') diff --git a/backend/open_webui/utils/auth.py b/backend/open_webui/utils/auth.py index 408b518c13..bfdbbafd05 100644 --- a/backend/open_webui/utils/auth.py +++ b/backend/open_webui/utils/auth.py @@ -386,6 +386,7 @@ async def get_current_user( # Scope-backed, so outer middleware (audit) can reuse the resolved user request.state.user = user + request.state.auth_type = 'api_key' return user # auth by jwt token @@ -437,6 +438,7 @@ async def get_current_user( # Scope-backed, so outer middleware (audit) can reuse the resolved user request.state.user = user + request.state.auth_type = 'jwt' return user else: raise HTTPException( diff --git a/backend/open_webui/utils/headers.py b/backend/open_webui/utils/headers.py index c8accbf676..813914e31f 100644 --- a/backend/open_webui/utils/headers.py +++ b/backend/open_webui/utils/headers.py @@ -5,6 +5,7 @@ from urllib.parse import quote import jwt from open_webui.env import ( + FORWARD_USER_INFO_HEADER_AUTH_TYPE, FORWARD_USER_INFO_HEADER_JWT, FORWARD_USER_INFO_HEADER_JWT_EXPIRES_SECONDS, FORWARD_USER_INFO_HEADER_JWT_SECRET, @@ -47,15 +48,20 @@ def _mint_forward_user_jwt(user: Any) -> str: return jwt.encode(payload, FORWARD_USER_INFO_HEADER_JWT_SECRET, algorithm='HS256') -def include_user_info_headers(headers: dict, user: Optional[Any] = None) -> dict: +def include_user_info_headers(headers: dict, user: Optional[Any] = None, *, request=None) -> dict: """ Forward user identity to external backends: signed JWT in FORWARD_USER_INFO_HEADER_JWT if FORWARD_USER_INFO_HEADER_JWT_SECRET is set; otherwise the legacy X-OpenWebUI-User-* headers. + Include the verified incoming auth type when a request provides it. """ if user is None: return headers + auth_type = getattr(getattr(request, 'state', None), 'auth_type', None) + if auth_type in ('api_key', 'jwt'): + headers = {**headers, FORWARD_USER_INFO_HEADER_AUTH_TYPE: auth_type} + if FORWARD_USER_INFO_HEADER_JWT_SECRET: try: token = _mint_forward_user_jwt(user) @@ -141,6 +147,7 @@ def parse_custom_headers( '{{USER_GROUPS}}': ','.join(group.name.strip() for group in user_groups) if user_groups else '', '{{USER_GROUP_IDS}}': ','.join(group.id for group in user_groups) if user_groups else '', '{{USER_AGENT}}': user_agent, + '{{AUTH_TYPE}}': getattr(getattr(request, 'state', None), 'auth_type', None) or '', } parsed_headers = {}