mirror of
https://github.com/open-webui/open-webui.git
synced 2026-11-07 08:17:07 +00:00
refac: apply OAuth role management on the token exchange endpoint
The endpoint now resolves the user's role through the same role management path the OAuth callback uses, and persists it when it differs. Where role management is enabled and no roles resolve, the exchange is denied instead of falling back to DEFAULT_USER_ROLE, which would demote an existing user. Deployments whose provider returns roles only in the ID token, or whose OAUTH_ROLES_CLAIM, OAUTH_ALLOWED_ROLES or OAUTH_ADMIN_ROLES configuration is incomplete, will see token exchange rejected where it previously issued a session.
This commit is contained in:
parent
29541cbb52
commit
4815a39839
2 changed files with 22 additions and 1 deletions
|
|
@ -1705,4 +1705,17 @@ async def token_exchange(
|
|||
detail='User not found. Please sign in via the web interface first.',
|
||||
)
|
||||
|
||||
role = await oauth_manager.get_user_role(user, user_data, deny_on_missing_roles=True)
|
||||
if user.role != role:
|
||||
await Users.update_user_role_by_id(user.id, role, db=db)
|
||||
user.role = role
|
||||
await publish_event(
|
||||
request,
|
||||
EVENTS.USER_ROLE_UPDATED,
|
||||
actor=user,
|
||||
subject_id=user.id,
|
||||
source='oauth',
|
||||
data={'role': role, 'provider': provider},
|
||||
)
|
||||
|
||||
return await create_session_response(request, user, db, source='oauth')
|
||||
|
|
|
|||
|
|
@ -1498,7 +1498,7 @@ class OAuthManager:
|
|||
log.error(f'Exception during token refresh for provider {provider}: {e}')
|
||||
return None
|
||||
|
||||
async def get_user_role(self, user, user_data):
|
||||
async def get_user_role(self, user, user_data, deny_on_missing_roles=False):
|
||||
auth_config = await get_oauth_runtime_config()
|
||||
user_count = await Users.get_num_users()
|
||||
if user and user_count == 1:
|
||||
|
|
@ -1551,6 +1551,14 @@ class OAuthManager:
|
|||
log.debug('Accepted user roles: %s', oauth_allowed_roles)
|
||||
log.debug('Accepted admin roles: %s', oauth_admin_roles)
|
||||
|
||||
# No ID token here to backfill claims from, so falling back to DEFAULT_USER_ROLE would demote the user.
|
||||
if not oauth_roles and deny_on_missing_roles:
|
||||
log.warning('OAuth role management enabled but no roles resolved for the user; denying token exchange')
|
||||
raise HTTPException(
|
||||
status.HTTP_403_FORBIDDEN,
|
||||
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
|
||||
)
|
||||
|
||||
# If roles are present in the token, they must match; otherwise deny access
|
||||
if oauth_roles:
|
||||
matched = False
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue