fix(auth): accept client credentials from Basic auth header in token endpoint (#1315)#2664
Open
afischh wants to merge 1 commit into
Open
Conversation
…endpoint When a client uses HTTP Basic authentication (RFC 6749 §2.3.1), its client_id and client_secret arrive in the Authorization header rather than the request body. ClientAuthenticator already validates Basic auth correctly for `client_secret_basic` clients, but it failed early with "Missing client_id" when client_id was absent from form data. TokenHandler also required client_id in form data for TokenRequest validation, causing a second failure path. Changes: - ClientAuthenticator.authenticate_request: extract client_id from Basic auth header when not present in form body, before the missing-id check - TokenHandler.handle: populate client_id from the already-authenticated client_info when absent from form data, so TokenRequest validates cleanly Two new tests cover the authorization_code and refresh_token grant flows with client_id supplied only via Authorization header. Fixes modelcontextprotocol#1315 Signed-off-by: afischh <afischh@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Fixes #1315.
When a client uses HTTP Basic authentication per RFC 6749 §2.3.1, its
client_idandclient_secretarrive in theAuthorizationheader rather than the request body. Two failure paths caused this to break:ClientAuthenticatorreadclient_idfrom form data first, and raisedAuthenticationError("Missing client_id")before it even reached the Basic auth parsing branch.TokenHandlervalidatedform_dataagainstTokenRequest(which requiresclient_id), so even if authentication had succeeded, the Pydantic model would reject the request.Fix
client_auth.py— before theMissing client_idguard, attempt to extractclient_idfrom aBasicAuthorizationheader if it is absent from form data:token.py— afterclient_authenticatorsuccessfully authenticates the request (soclient_infois already verified), populateclient_idfromclient_infowhen absent from form data:This is safe because
client_infois the result of successful authentication — we already know who the client is.Tests
Two new tests in
test_auth_integration.py:test_basic_auth_without_client_id_in_body—authorization_codegrant withclient_idonly inAuthorizationheader →200 OKwith access tokentest_basic_auth_refresh_token_without_client_id_in_body—refresh_tokengrant withclient_idonly inAuthorizationheader →200 OKwith new access tokenAll 66 existing auth tests continue to pass.
🤖 Generated with Claude Code