Validate the iss authorization-response parameter (RFC 9207 / SEP-2468) (#2921)

This commit is contained in:
Marcelo Trylesinski 2026-06-20 16:54:18 +01:00 • committed by GitHub
commit 48cf4950dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 335 additions and 103 deletions

View file

@ -43,7 +43,7 @@ from mcp.client.auth.extensions.client_credentials import (
)
from mcp.client.context import ClientRequestContext
from mcp.client.streamable_http import streamable_http_client
from mcp.shared.auth import OAuthClientInformationFull, OAuthClientMetadata, OAuthToken
from mcp.shared.auth import AuthorizationCodeResult, OAuthClientInformationFull, OAuthClientMetadata, OAuthToken
# Set up logging to stderr (stdout is for conformance test output)
logging.basicConfig(
@ -119,6 +119,7 @@ class ConformanceOAuthCallbackHandler:
def __init__(self) -> None:
self._auth_code: str | None = None
self._state: str | None = None
self._iss: str | None = None
async def handle_redirect(self, authorization_url: str) -> None:
"""Fetch the authorization URL and extract the auth code from the redirect."""
@ -140,6 +141,8 @@ class ConformanceOAuthCallbackHandler:
self._auth_code = query_params["code"][0]
state_values = query_params.get("state")
self._state = state_values[0] if state_values else None
iss_values = query_params.get("iss")
self._iss = iss_values[0] if iss_values else None
logger.debug(f"Got auth code from redirect: {self._auth_code[:10]}...")
return
else:
@ -149,15 +152,15 @@ class ConformanceOAuthCallbackHandler:
else:
raise RuntimeError(f"Expected redirect response, got {response.status_code} from {authorization_url}")
async def handle_callback(self) -> tuple[str, str | None]:
"""Return the captured auth code and state."""
async def handle_callback(self) -> AuthorizationCodeResult:
"""Return the captured auth code, state, and iss."""
if self._auth_code is None:
raise RuntimeError("No authorization code available - was handle_redirect called?")
auth_code = self._auth_code
state = self._state
result = AuthorizationCodeResult(code=self._auth_code, state=self._state, iss=self._iss)
self._auth_code = None
self._state = None
return auth_code, state
self._iss = None
return result
# --- Scenario Handlers ---

View file

@ -44,6 +44,15 @@ client:
- auth/token-endpoint-auth-post
- auth/token-endpoint-auth-none
- auth/offline-access-not-supported
# SEP-2468 (authorization response iss parameter) is implemented, but these
# 2026-introduced scenarios reach DCR and so still fail the application_type
# check above; they unblock with SEP-837, not SEP-2468.
- auth/iss-supported
- auth/iss-not-advertised
- auth/iss-supported-missing
- auth/iss-wrong-issuer
- auth/iss-unexpected
- auth/iss-normalized
# --- Auth scenarios cut short by the 2026 connection lifecycle ---
# The auth fixture flow drives the 2025 stateful lifecycle; the 2026-mode
@ -65,14 +74,6 @@ client:
- http-invalid-tool-headers
# SEP-2106 (JSON Schema $ref handling): client still dereferences network $refs.
- json-schema-ref-no-deref
# SEP-2468 (authorization response iss parameter): not implemented in the client.
- auth/iss-supported
- auth/iss-not-advertised
- auth/iss-supported-missing
- auth/iss-wrong-issuer
- auth/iss-unexpected
- auth/iss-normalized
- auth/metadata-issuer-mismatch
# SEP-2352 (authorization server migration): client does not re-register when
# PRM authorization_servers changes.
- auth/authorization-server-migration

View file

@ -24,20 +24,21 @@ client:
- http-invalid-tool-headers
# SEP-2106 (JSON Schema $ref handling): client still dereferences network $refs.
- json-schema-ref-no-deref
# SEP-2468 (authorization response iss parameter): not implemented in the client.
# SEP-2352 (authorization server migration): client does not re-register when
# PRM authorization_servers changes.
- auth/authorization-server-migration
# SEP-837 (application_type during DCR): the check fires on every non-legacy
# spec version (the default LATEST is 2026-07-28). The client omits
# application_type during Dynamic Client Registration, so every scenario that
# reaches DCR fails it. SEP-2468 iss validation is implemented, so these now
# fail only on the application_type check, not on iss.
- auth/offline-access-not-supported
- auth/iss-supported
- auth/iss-not-advertised
- auth/iss-supported-missing
- auth/iss-wrong-issuer
- auth/iss-unexpected
- auth/iss-normalized
- auth/metadata-issuer-mismatch
# SEP-2352 (authorization server migration): client does not re-register when
# PRM authorization_servers changes.
- auth/authorization-server-migration
# SEP-837 (application_type during DCR): the check only fires on draft-version
# runs; this draft scenario is the one place the client still hits it.
- auth/offline-access-not-supported
# --- Pre-existing scenarios that fail on checks added after conformance 0.1.15 ---
# SEP-2350 (scope step-up): WARNING-only; the expected-failures evaluator