Skip to content

fix(client): don't send client_id in token body under client_secret_basic#3159

Draft
SpiliosDimakopoulos wants to merge 1 commit into
modelcontextprotocol:mainfrom
SpiliosDimakopoulos:fix-oauth-client-id-in-basic-auth-body
Draft

fix(client): don't send client_id in token body under client_secret_basic#3159
SpiliosDimakopoulos wants to merge 1 commit into
modelcontextprotocol:mainfrom
SpiliosDimakopoulos:fix-oauth-client-id-in-basic-auth-body

Conversation

@SpiliosDimakopoulos

Copy link
Copy Markdown

Fixes #3138

What

Under token_endpoint_auth_method = client_secret_basic, the OAuth client sends
credentials via Authorization: Basic ... — but prepare_token_auth() only
stripped client_secret from the request body, leaving client_id in. RFC 6749
§2.3 requires that with Basic auth, client credentials not also appear in the
body. Strict token endpoints (Keycloak, Okta in strict mode) reject this as two
authentication methods in a single request.

Fix

One-line change: strip client_id alongside client_secret from the body when
auth_method == "client_secret_basic".

Testing

Two existing tests in tests/client/test_auth.py explicitly asserted the old
(buggy) behavior — assert "client_id=test%40client" in content # client_id still in body. Updated both to assert its absence instead, and added the same
check to the refresh-token test for symmetry.

uv run pytest tests/client/, uv run ruff check ., uv run ruff format --check .,
uv run pyright all pass.

Disclosure

I used AI (Claude) to help draft this fix; I've reviewed and understand the
change and I'm happy to answer questions about it.

…asic

RFC 6749 §2.3: with HTTP Basic auth, client credentials must not also
appear in the request body. prepare_token_auth() already stripped
client_secret for client_secret_basic but left client_id in, so strict
token endpoints (Keycloak, Okta strict mode) saw two authentication
methods in one request and rejected it. Strip client_id too.

Two existing tests asserted the old behavior explicitly (client_id
present in the body) -- updated them to assert its absence instead.

Fixes modelcontextprotocol#3138
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OAuth client sends client_id in token body under client_secret_basic (strict servers reject as multiple auth methods)

1 participant