[GH-ISSUE #9452] OIDC login fails when email claim only available via userinfo endpoint #54177

Closed
opened 2026-05-05 15:54:10 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @mitomac on GitHub (Feb 6, 2025).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/9452

OIDC authentication issue: userinfo endpoint not called when token contains partial claims

Description

When an OIDC provider returns partial userinfo claims in the token but provides complete claims via the userinfo endpoint, authentication fails with "email is missing" error.

Environment

  • Open WebUI version: v0.5.10 (latest)
  • OIDC Provider: Duke University OIDC
  • OAuth Flow: Authorization Code Grant
  • Affected File: /app/backend/open_webui/utils/oauth.py

Current Behavior

The code checks for userinfo in the token and only calls the userinfo endpoint if no data is present. However, some OIDC providers (like Duke) include partial claims in the token but require the userinfo endpoint call for complete profile information.

Expected Behavior

The code should call the userinfo endpoint if required claims (like email) are missing, even if some userinfo data exists in the token.

Debugging Evidence

Debug logs show the issue clearly:

  1. Token contains partial userinfo:
'userinfo': {
    'sub': 'user123@duke.edu',
    'aud': 'client-id-123',
    'kid': 'rsa1',
    # ... but no email claim
}
  1. Userinfo endpoint provides complete data:
{
    'sub': 'user123@duke.edu',
    'netID': 'user123',
    'name': 'Example User, Ph.D.',
    'email': 'user@duke.edu',
    'email_verified': False
    # ... full profile data
}

Current Code

In /app/backend/open_webui/utils/oauth.py:

user_data: UserInfo = token.get("userinfo")
if not user_data:
    user_data: UserInfo = await client.userinfo(token=token)

Proposed Fix

user_data: UserInfo = token.get("userinfo")
if not user_data or "email" not in user_data:
    user_data: UserInfo = await client.userinfo(token=token)

Impact

This affects any OIDC provider that:

  1. Includes partial claims in the token response
  2. Requires userinfo endpoint call for complete profile data
  3. Follows the OIDC spec pattern of separating token and userinfo responses

The current implementation prevents users from these providers from logging in, even when all required scopes are properly configured.

Originally created by @mitomac on GitHub (Feb 6, 2025). Original GitHub issue: https://github.com/open-webui/open-webui/issues/9452 # OIDC authentication issue: userinfo endpoint not called when token contains partial claims ## Description When an OIDC provider returns partial userinfo claims in the token but provides complete claims via the userinfo endpoint, authentication fails with "email is missing" error. ## Environment - Open WebUI version: v0.5.10 (latest) - OIDC Provider: Duke University OIDC - OAuth Flow: Authorization Code Grant - Affected File: `/app/backend/open_webui/utils/oauth.py` ## Current Behavior The code checks for userinfo in the token and only calls the userinfo endpoint if no data is present. However, some OIDC providers (like Duke) include partial claims in the token but require the userinfo endpoint call for complete profile information. ## Expected Behavior The code should call the userinfo endpoint if required claims (like email) are missing, even if some userinfo data exists in the token. ## Debugging Evidence Debug logs show the issue clearly: 1. Token contains partial userinfo: ```python 'userinfo': { 'sub': 'user123@duke.edu', 'aud': 'client-id-123', 'kid': 'rsa1', # ... but no email claim } ``` 2. Userinfo endpoint provides complete data: ```python { 'sub': 'user123@duke.edu', 'netID': 'user123', 'name': 'Example User, Ph.D.', 'email': 'user@duke.edu', 'email_verified': False # ... full profile data } ``` ## Current Code In `/app/backend/open_webui/utils/oauth.py`: ```python user_data: UserInfo = token.get("userinfo") if not user_data: user_data: UserInfo = await client.userinfo(token=token) ``` ## Proposed Fix ```python user_data: UserInfo = token.get("userinfo") if not user_data or "email" not in user_data: user_data: UserInfo = await client.userinfo(token=token) ``` ## Impact This affects any OIDC provider that: 1. Includes partial claims in the token response 2. Requires userinfo endpoint call for complete profile data 3. Follows the OIDC spec pattern of separating token and userinfo responses The current implementation prevents users from these providers from logging in, even when all required scopes are properly configured.
Author
Owner

@tjbck commented on GitHub (Feb 6, 2025):

PR Welcome!

<!-- gh-comment-id:2638457303 --> @tjbck commented on GitHub (Feb 6, 2025): PR Welcome!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#54177