From eb96fb78bc27ae841eb91206db134635b4c1b65f Mon Sep 17 00:00:00 2001 From: sings-to-bees-on-wednesdays <222684290+sings-to-bees-on-wednesdays@users.noreply.github.com> Date: Fri, 25 Jul 2025 05:06:12 +0000 Subject: [PATCH] fix(auth_utils): make header comparison case-insensitive (#12950) If the user specified in the configuration e.g. "user_header_name: X-OpenWebUI-User-Email", here we were looking for a dict key "X-OpenWebUI-User-Email" when the dict actually contained "x-openwebui-user-email". Switch to iteration and case insensitive string comparison instead to fix this. This fixes customer budget enforcement when the customer ID is passed in as a header rather than as a "user" value in the body. --- litellm/proxy/auth/auth_utils.py | 8 +++++--- tests/local_testing/test_auth_utils.py | 7 +++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/litellm/proxy/auth/auth_utils.py b/litellm/proxy/auth/auth_utils.py index 4bef5e0a20..3261d15889 100644 --- a/litellm/proxy/auth/auth_utils.py +++ b/litellm/proxy/auth/auth_utils.py @@ -490,9 +490,11 @@ def get_end_user_id_from_request_body( custom_header_name_to_check = general_settings.get(user_id_header_config_key) if custom_header_name_to_check and isinstance(custom_header_name_to_check, str): - user_id_from_header = request_headers.get(custom_header_name_to_check) - if user_id_from_header is not None and user_id_from_header.strip(): - return str(user_id_from_header) + for header_name, header_value in request_headers.items(): + if header_name.lower() == custom_header_name_to_check.lower(): + user_id_from_header = header_value + if user_id_from_header.strip(): + return str(user_id_from_header) # Check 2: 'user' field in request_body (commonly OpenAI) if "user" in request_body and request_body["user"] is not None: diff --git a/tests/local_testing/test_auth_utils.py b/tests/local_testing/test_auth_utils.py index e2ddbca603..b696eb2199 100644 --- a/tests/local_testing/test_auth_utils.py +++ b/tests/local_testing/test_auth_utils.py @@ -169,6 +169,13 @@ def test_get_end_user_id_from_request_body_always_returns_str(): }, "header-priority" ), + # Test 12: user_header_name is matched case-insensitively + ( + {"x-user-id": "lowercase-header-user"}, + {"user_header_name": "X-User-ID"}, + {"user": "body-user-456"}, + "lowercase-header-user" + ), ] ) def test_get_end_user_id_from_request_body_with_user_header_name(