|
36 | 36 | from key_value.aio.protocols import AsyncKeyValue |
37 | 37 | from key_value.aio.stores.disk import DiskStore |
38 | 38 | from key_value.aio.wrappers.encryption import FernetEncryptionWrapper |
39 | | -from mcp.server.auth.handlers.token import TokenErrorResponse, TokenSuccessResponse |
| 39 | +from mcp.server.auth.handlers.token import TokenErrorResponse |
40 | 40 | from mcp.server.auth.handlers.token import TokenHandler as _SDKTokenHandler |
41 | 41 | from mcp.server.auth.json_response import PydanticJSONResponse |
42 | 42 | from mcp.server.auth.middleware.client_auth import ClientAuthenticator |
@@ -533,12 +533,6 @@ class TokenHandler(_SDKTokenHandler): |
533 | 533 |
|
534 | 534 | This handler transforms 401 responses with `unauthorized_client` to use |
535 | 535 | `invalid_client` instead, making the error semantics correct per OAuth spec. |
536 | | -
|
537 | | - Per OAuth 2.1 Section 5.3: "The authorization server MAY return an HTTP 401 |
538 | | - (Unauthorized) status code to indicate which HTTP authentication schemes |
539 | | - are supported." |
540 | | -
|
541 | | - Per MCP spec: "Invalid or expired tokens MUST receive a HTTP 401 response." |
542 | 536 | """ |
543 | 537 |
|
544 | 538 | async def handle(self, request: Any): |
@@ -566,35 +560,6 @@ async def handle(self, request: Any): |
566 | 560 |
|
567 | 561 | return response |
568 | 562 |
|
569 | | - def response(self, obj: TokenSuccessResponse | TokenErrorResponse): |
570 | | - """Override response method to provide OAuth 2.1 compliant error handling.""" |
571 | | - # Check if this is a client authentication failure (not just unauthorized for grant type) |
572 | | - # unauthorized_client can mean two things: |
573 | | - # 1. Client authentication failed (client_id not found or wrong credentials) -> invalid_client 401 |
574 | | - # 2. Client not authorized for this grant type -> unauthorized_client 400 (correct per spec) |
575 | | - if ( |
576 | | - isinstance(obj, TokenErrorResponse) |
577 | | - and obj.error == "unauthorized_client" |
578 | | - and obj.error_description |
579 | | - and "Invalid client_id" in obj.error_description |
580 | | - ): |
581 | | - # Transform client auth failure to OAuth 2.1 compliant response |
582 | | - return PydanticJSONResponse( |
583 | | - content=TokenErrorResponse( |
584 | | - error="invalid_client", |
585 | | - error_description=obj.error_description, |
586 | | - error_uri=obj.error_uri, |
587 | | - ), |
588 | | - status_code=401, |
589 | | - headers={ |
590 | | - "Cache-Control": "no-store", |
591 | | - "Pragma": "no-cache", |
592 | | - }, |
593 | | - ) |
594 | | - |
595 | | - # Otherwise use default behavior from parent class |
596 | | - return super().response(obj) |
597 | | - |
598 | 563 |
|
599 | 564 | class OAuthProxy(OAuthProvider): |
600 | 565 | """OAuth provider that presents a DCR-compliant interface while proxying to non-DCR IDPs. |
|
0 commit comments