-
Notifications
You must be signed in to change notification settings - Fork 624
fix(auth): ignore non-metadata JSON when probing for protected resource metadata #1204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
easyinplay
wants to merge
2
commits into
modelcontextprotocol:main
Choose a base branch
from
easyinplay:fix-prm-probe-non-metadata-json
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+150
−6
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
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
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
discover_resource_metadata_urlhas already returned the base URL before rejecting the response body, so returningOk(None)sends control back toresolve_metadataand skips all the protected-resource well-known candidates.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, and the first commit message named the mechanism without the fix following through: it says the base URL 200 makes the well-known fallbacks never run, and then only softened the failure that came after. Pushed a second commit that fixes it where you point.
The deciding line is in
probe_resource_metadata_url:"200 means this url is the document" holds for the
.well-knowncandidates it is called with in the loop, and not for the first call, which is passed the resource itself. RFC 9728 publishes the document at the well-known URI and advertises it through theresource_metadataparameter of a challenge, so a 200 from the resource is the resource answering. Only the 401 branch says anything at that first call, which is nowprobe_resource_endpoint_for_challenge; the.well-knownprobe is unchanged.What that was costing, from the recorded requests with the old probe and a health payload at the base URL:
The base URL twice, then straight to authorization server discovery.
https://mcp.example.com/.well-known/oauth-protected-resourceis never requested, so a document published there is unreachable no matter what the fetch does with the body.The check from the first commit stays. A
.well-knownurl can answer 200 with something unrelated too, and every field ofResourceServerMetadatabeing optional turns that into an all-Nonevalue that fails validation fatally rather than falling through.Two tests, and both fail with the corresponding half reverted:
resolve_metadata_reaches_the_well_known_document_past_a_non_metadata_base_urlasserts the well-known url is actually requested and that resolution comes back asProtectedResourceMetadata. Restore the old probe call and it fails on the assertion above, printing the four requests.resolve_metadata_ignores_a_well_known_url_that_is_not_a_metadata_documentcovers the remaining guard. Drop the guard and it fails withMetadataError("Protected resource metadata missing required resource field"), the error this PR started from.The test I had before asserted the fall-through you flagged, so it is gone.
cargo clippy --all-targets --all-features -- -D warningsis clean andcargo test -p rmcp --all-featuresis 499 passed, withdefault_http_client_preserves_connection_failure_causefailing identically on an untouchedmainhere (it asserts a connection error string my platform words differently).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
WWW-Authenticatepoints to the metadata URL, the server is explicitly saying that this document contains the metadata. If the body is{}, it used to raise a hardmissing required resource fielderror. Now it returnsOk(None), soresolve_metadata_from_challengecontinues with authorization server discovery and then falls back to the legacy endpoint. As a result, it drops the RFC 8707 resource binding without reporting it.