Skip to content

Commit 41b3d91

Browse files
committed
Update async_auth_flow
1 parent cfb3f7e commit 41b3d91

File tree

1 file changed

+53
-85
lines changed

1 file changed

+53
-85
lines changed

src/mcp/client/auth.py

Lines changed: 53 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -514,92 +514,60 @@ async def async_auth_flow(self, request: httpx.Request) -> AsyncGenerator[httpx.
514514
# Capture protocol version from request headers
515515
self.context.protocol_version = request.headers.get(MCP_PROTOCOL_VERSION)
516516

517-
# Perform OAuth flow if not authenticated
518-
if not self.context.is_token_valid():
519-
try:
520-
# OAuth flow must be inline due to generator constraints
521-
# Step 1: Discover protected resource metadata (spec revision 2025-06-18)
522-
discovery_request = await self._discover_protected_resource()
523-
discovery_response = yield discovery_request
524-
await self._handle_protected_resource_response(discovery_response)
525-
526-
# Step 2: Discover OAuth metadata (with fallback for legacy servers)
527-
oauth_request = await self._discover_oauth_metadata()
528-
oauth_response = yield oauth_request
529-
handled = await self._handle_oauth_metadata_response(oauth_response, is_fallback=False)
530-
531-
# If path-aware discovery failed with 404, try fallback to root
532-
if not handled:
533-
fallback_request = await self._discover_oauth_metadata_fallback()
534-
fallback_response = yield fallback_request
535-
await self._handle_oauth_metadata_response(fallback_response, is_fallback=True)
536-
537-
# Step 3: Register client if needed
538-
registration_request = await self._register_client()
539-
if registration_request:
540-
registration_response = yield registration_request
541-
await self._handle_registration_response(registration_response)
542-
543-
# Step 4: Perform authorization
544-
auth_code, code_verifier = await self._perform_authorization()
545-
546-
# Step 5: Exchange authorization code for tokens
547-
token_request = await self._exchange_token(auth_code, code_verifier)
548-
token_response = yield token_request
549-
await self._handle_token_response(token_response)
550-
except Exception as e:
551-
logger.error(f"OAuth flow error: {e}")
552-
raise
553-
554-
# Add authorization header and make request
555-
self._add_auth_header(request)
517+
if self.context.is_token_valid():
518+
self._add_auth_header(request)
519+
556520
response = yield request
557521

558-
# Handle 401 responses
559-
if response.status_code == 401 and self.context.can_refresh_token():
560-
# Try to refresh token
561-
refresh_request = await self._refresh_token()
562-
refresh_response = yield refresh_request
522+
if response.status_code == 401:
523+
if self.context.can_refresh_token():
524+
# Try to refresh token
525+
refresh_request = await self._refresh_token()
526+
refresh_response = yield refresh_request
563527

564-
if await self._handle_refresh_response(refresh_response):
565-
# Retry original request with new token
566-
self._add_auth_header(request)
567-
yield request
528+
if not await self._handle_refresh_response(refresh_response):
529+
# Refresh failed, need full re-authentication
530+
self._initialized = False
568531
else:
569-
# Refresh failed, need full re-authentication
570-
self._initialized = False
571-
572-
# OAuth flow must be inline due to generator constraints
573-
# Step 1: Discover protected resource metadata (spec revision 2025-06-18)
574-
discovery_request = await self._discover_protected_resource()
575-
discovery_response = yield discovery_request
576-
await self._handle_protected_resource_response(discovery_response)
577-
578-
# Step 2: Discover OAuth metadata (with fallback for legacy servers)
579-
oauth_request = await self._discover_oauth_metadata()
580-
oauth_response = yield oauth_request
581-
handled = await self._handle_oauth_metadata_response(oauth_response, is_fallback=False)
582-
583-
# If path-aware discovery failed with 404, try fallback to root
584-
if not handled:
585-
fallback_request = await self._discover_oauth_metadata_fallback()
586-
fallback_response = yield fallback_request
587-
await self._handle_oauth_metadata_response(fallback_response, is_fallback=True)
588-
589-
# Step 3: Register client if needed
590-
registration_request = await self._register_client()
591-
if registration_request:
592-
registration_response = yield registration_request
593-
await self._handle_registration_response(registration_response)
594-
595-
# Step 4: Perform authorization
596-
auth_code, code_verifier = await self._perform_authorization()
597-
598-
# Step 5: Exchange authorization code for tokens
599-
token_request = await self._exchange_token(auth_code, code_verifier)
600-
token_response = yield token_request
601-
await self._handle_token_response(token_response)
602-
603-
# Retry with new tokens
604-
self._add_auth_header(request)
605-
yield request
532+
self.context.clear_tokens()
533+
534+
# If we don't have valid tokens after refresh, perform OAuth flow
535+
if not self.context.is_token_valid():
536+
try:
537+
# OAuth flow must be inline due to generator constraints
538+
# Step 1: Discover protected resource metadata (spec revision 2025-06-18)
539+
discovery_request = await self._discover_protected_resource()
540+
discovery_response = yield discovery_request
541+
await self._handle_protected_resource_response(discovery_response)
542+
543+
# Step 2: Discover OAuth metadata (with fallback for legacy servers)
544+
oauth_request = await self._discover_oauth_metadata()
545+
oauth_response = yield oauth_request
546+
handled = await self._handle_oauth_metadata_response(oauth_response, is_fallback=False)
547+
548+
# If path-aware discovery failed with 404, try fallback to root
549+
if not handled:
550+
fallback_request = await self._discover_oauth_metadata_fallback()
551+
fallback_response = yield fallback_request
552+
await self._handle_oauth_metadata_response(fallback_response, is_fallback=True)
553+
554+
# Step 3: Register client if needed
555+
registration_request = await self._register_client()
556+
if registration_request:
557+
registration_response = yield registration_request
558+
await self._handle_registration_response(registration_response)
559+
560+
# Step 4: Perform authorization
561+
auth_code, code_verifier = await self._perform_authorization()
562+
563+
# Step 5: Exchange authorization code for tokens
564+
token_request = await self._exchange_token(auth_code, code_verifier)
565+
token_response = yield token_request
566+
await self._handle_token_response(token_response)
567+
except Exception as e:
568+
logger.error(f"OAuth flow error: {e}")
569+
raise
570+
571+
# Retry with new tokens
572+
self._add_auth_header(request)
573+
yield request

0 commit comments

Comments
 (0)