mirror of
https://github.com/open-webui/open-webui.git
synced 2026-10-18 04:43:55 +00:00
fix: OAuth token refresh ignores the client_secret_basic auth method (#32507)
When Open WebUI authenticates to the OAuth provider with client_secret_basic, either because OAUTH_TOKEN_ENDPOINT_AUTH_METHOD is set to it or because an MCP tool server's OAuth provider only offers that method, sign-in sent the client ID and secret in an HTTP Basic header but the token refresh always put them in the request body. Providers that only accept Basic rejected every refresh with invalid_client, so once the access token expired Open WebUI deleted the user's saved OAuth tokens, and model connections and tool servers set to forward the user's OAuth token stopped working until the user signed in again. The refresh now authenticates the same way sign-in does for client_secret_basic, with the credentials only in the Basic header. Setups using client_secret_post, or leaving the setting unset, still send the credentials in the request body exactly as before. Fixes #32506
This commit is contained in:
parent
ec39df7da5
commit
ae6793dd4f
1 changed files with 16 additions and 2 deletions
|
|
@ -1186,8 +1186,14 @@ class OAuthClientManager:
|
|||
if should_send_oauth_resource(client_info):
|
||||
refresh_data['resource'] = client_info.resource
|
||||
|
||||
client_auth = None
|
||||
if hasattr(client, 'client_secret') and client.client_secret:
|
||||
refresh_data['client_secret'] = client.client_secret
|
||||
if client.client_kwargs.get('token_endpoint_auth_method') == 'client_secret_basic':
|
||||
client_auth = aiohttp.BasicAuth(client.client_id, client.client_secret)
|
||||
# Some providers reject a body client_id next to Basic as a second credential (#19415)
|
||||
del refresh_data['client_id']
|
||||
else:
|
||||
refresh_data['client_secret'] = client.client_secret
|
||||
|
||||
# Add scope if available in client kwargs (some providers require it on refresh)
|
||||
if (
|
||||
|
|
@ -1202,6 +1208,7 @@ class OAuthClientManager:
|
|||
async with session_http.post(
|
||||
token_endpoint,
|
||||
data=refresh_data,
|
||||
auth=client_auth,
|
||||
headers={'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
ssl=AIOHTTP_CLIENT_SESSION_SSL,
|
||||
) as r:
|
||||
|
|
@ -1538,9 +1545,15 @@ class OAuthManager:
|
|||
'refresh_token': token_data['refresh_token'],
|
||||
'client_id': client.client_id,
|
||||
}
|
||||
client_auth = None
|
||||
# Add client_secret if available (some providers require it)
|
||||
if hasattr(client, 'client_secret') and client.client_secret:
|
||||
refresh_data['client_secret'] = client.client_secret
|
||||
if client.client_kwargs.get('token_endpoint_auth_method') == 'client_secret_basic':
|
||||
client_auth = aiohttp.BasicAuth(client.client_id, client.client_secret)
|
||||
if not OAUTH_ACCESS_TOKEN_REQUEST_INCLUDE_CLIENT_ID:
|
||||
del refresh_data['client_id']
|
||||
else:
|
||||
refresh_data['client_secret'] = client.client_secret
|
||||
|
||||
# Add scope if available in client kwargs (some providers require it on refresh)
|
||||
if (
|
||||
|
|
@ -1555,6 +1568,7 @@ class OAuthManager:
|
|||
async with session_http.post(
|
||||
token_endpoint,
|
||||
data=refresh_data,
|
||||
auth=client_auth,
|
||||
headers={'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
ssl=AIOHTTP_CLIENT_SESSION_SSL,
|
||||
) as r:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue