diff --git a/litellm/proxy/management_endpoints/ui_sso.py b/litellm/proxy/management_endpoints/ui_sso.py index 304a1b47896..e983a0b0707 100644 --- a/litellm/proxy/management_endpoints/ui_sso.py +++ b/litellm/proxy/management_endpoints/ui_sso.py @@ -2980,8 +2980,9 @@ class SSOAuthenticationHandler: ) else: verbose_proxy_logger.warning( - "Userinfo endpoint returned %s, falling back to id_token", + "Userinfo endpoint returned %s (body: %s), falling back to id_token", resp.status_code, + resp.text[:500], ) except Exception as e: verbose_proxy_logger.warning( diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index fbea1a02cd5..6404e38e2fc 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -1494,7 +1494,8 @@ native_background_mode: List[ polling_cache_ttl: int = 3600 # Default 1 hour TTL for polling cache user_custom_auth = None user_custom_key_generate = None -# Sentinel: prevents PKCE-no-Redis advisory from re-logging on config hot-reload +# Sentinel: prevents PKCE-no-Redis advisory from re-logging on config hot-reload. +# Tests that need to reset it can patch 'litellm.proxy.proxy_server._pkce_no_redis_warning_emitted'. _pkce_no_redis_warning_emitted: bool = False user_custom_sso = None user_custom_ui_sso_sign_in_handler = None diff --git a/tests/test_litellm/proxy/management_endpoints/test_ui_sso.py b/tests/test_litellm/proxy/management_endpoints/test_ui_sso.py index 602ec6afcaf..ca480b84420 100644 --- a/tests/test_litellm/proxy/management_endpoints/test_ui_sso.py +++ b/tests/test_litellm/proxy/management_endpoints/test_ui_sso.py @@ -3422,9 +3422,11 @@ class TestPKCEFunctionality: assert "auth" in kwargs assert isinstance(kwargs["auth"], httpx.BasicAuth) # Verify code_verifier is in the POST body (essential PKCE field) - assert kwargs.get("data", {}).get("code_verifier") == "verifier_abc" - # Verify credentials are NOT double-sent in the POST body when using Basic Auth post_data = kwargs.get("data", {}) + assert post_data.get("code_verifier") == "verifier_abc" + # Verify redirect_uri is forwarded (required by strict OAuth providers) + assert post_data.get("redirect_uri") == "https://proxy.example.com/callback" + # Verify credentials are NOT double-sent in the POST body when using Basic Auth assert "client_secret" not in post_data, "client_secret must not appear in POST body when using Basic Auth" assert "client_id" not in post_data, "client_id must not appear in POST body when using Basic Auth (include_client_id=False)" return mock_response @@ -3484,6 +3486,7 @@ class TestPKCEFunctionality: assert "client_id" in data assert "client_secret" in data assert data.get("code_verifier") == "verifier_xyz", "code_verifier must be in POST body" + assert data.get("redirect_uri") == "https://proxy.example.com/callback", "redirect_uri must be forwarded" mock = MagicMock() mock.status_code = 200 mock.json.return_value = token_resp