-
Notifications
You must be signed in to change notification settings - Fork 2.6k
RFC 8707 Resource Indicators Implementation #991
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
Merged
Merged
Changes from 34 commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
5c2097a
Implement separate Authorization Server (AS) / Resource Server (RS)
ihrpr 7ab353f
update readme
ihrpr 59d9bfd
update comment
ihrpr e087e30
server
ihrpr 395c3ac
clean up
ihrpr beef439
fix tests
ihrpr 36d1e0d
add legacy mcp server as AS server for testing backwards compatibility
ihrpr f2e31ca
json fix
ihrpr 8862507
remove use of http clients in auth provider
ihrpr 90005e4
refactor
ihrpr 86283c3
remove state machine, it overcomplicates things
ihrpr 38c574f
ruff
ihrpr 8080d87
fix comment
ihrpr a565625
comments
ihrpr a8c99eb
refactor legacy AS+MCP and AS examples
ihrpr 76dbf53
improve comments
ihrpr 9b2e3df
pyright and ruff
ihrpr 926745a
simplify server examples, address comments
ihrpr fd353c5
remove host param from example servers
ihrpr ae4b6dc
RFC 8707 Resource Indicators Implementation
ihrpr 695531f
clean up notes
ihrpr 5208468
ruff
ihrpr ef8d546
add readme
ihrpr 7787621
Merge branch 'ihrpr/auth2' into ihrpr/RFC-8707
ihrpr 99e1db2
fix dependency
ihrpr f1e4e02
Merge branch 'ihrpr/auth2' into ihrpr/RFC-8707
ihrpr 3cc55fc
fix readme
ihrpr a024ca8
fix readme
ihrpr d7990fc
Merge branch 'ihrpr/auth2' into ihrpr/RFC-8707
ihrpr e59fbdf
apply suggested changes
ihrpr 96acbc1
fix AS example and add readme
ihrpr 9b400b2
readme
ihrpr 681a718
format
ihrpr c5e3c6d
Merge branch 'main' into ihrpr/RFC-8707
ihrpr c57e05e
fix after merge
ihrpr 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
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
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
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
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
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
"""Utilities for OAuth 2.0 Resource Indicators (RFC 8707).""" | ||
|
||
from urllib.parse import urlparse, urlsplit, urlunsplit | ||
|
||
from pydantic import AnyUrl, HttpUrl | ||
|
||
|
||
def resource_url_from_server_url(url: str | HttpUrl | AnyUrl) -> str: | ||
"""Convert server URL to canonical resource URL per RFC 8707. | ||
|
||
RFC 8707 section 2 states that resource URIs "MUST NOT include a fragment component". | ||
Returns absolute URI with lowercase scheme/host for canonical form. | ||
|
||
Args: | ||
url: Server URL to convert | ||
|
||
Returns: | ||
Canonical resource URL string | ||
""" | ||
# Convert to string if needed | ||
url_str = str(url) | ||
|
||
# Parse the URL and remove fragment, create canonical form | ||
parsed = urlsplit(url_str) | ||
canonical = urlunsplit(parsed._replace(scheme=parsed.scheme.lower(), netloc=parsed.netloc.lower(), fragment="")) | ||
|
||
return canonical | ||
|
||
|
||
def check_resource_allowed(requested_resource: str, configured_resource: str) -> bool: | ||
"""Check if a requested resource URL matches a configured resource URL. | ||
|
||
A requested resource matches if it has the same scheme, domain, port, | ||
and its path starts with the configured resource's path. This allows | ||
hierarchical matching where a token for a parent resource can be used | ||
for child resources. | ||
|
||
Args: | ||
requested_resource: The resource URL being requested | ||
configured_resource: The resource URL that has been configured | ||
|
||
Returns: | ||
True if the requested resource matches the configured resource | ||
""" | ||
# Parse both URLs | ||
requested = urlparse(requested_resource) | ||
configured = urlparse(configured_resource) | ||
|
||
# Compare scheme, host, and port (origin) | ||
if requested.scheme.lower() != configured.scheme.lower() or requested.netloc.lower() != configured.netloc.lower(): | ||
return False | ||
|
||
# Handle cases like requested=/foo and configured=/foo/ | ||
requested_path = requested.path | ||
configured_path = configured.path | ||
|
||
# If requested path is shorter, it cannot be a child | ||
if len(requested_path) < len(configured_path): | ||
return False | ||
|
||
# Check if the requested path starts with the configured path | ||
# Ensure both paths end with / for proper comparison | ||
# This ensures that paths like "/api123" don't incorrectly match "/api" | ||
if not requested_path.endswith("/"): | ||
requested_path += "/" | ||
if not configured_path.endswith("/"): | ||
configured_path += "/" | ||
|
||
return requested_path.startswith(configured_path) |
Oops, something went wrong.
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.
Would be good to add expectations on resource param to tests/client/test_auth.py similar to https://github.com/modelcontextprotocol/typescript-sdk/pull/638/files#diff-68dc66b14905d1fc01dc142e244a7e13fbdf88062d3a0b426983c333ccdfc9ed
(doesn't look like there's tests for authorize.py or for provider.py yet, not sure how hard they'd be to add)