Skip to content

[Client] Support completing OAuth authorization in a later request - #660

Open
bbdu3 wants to merge 1 commit into
modelcontextprotocol:feat-client-authfrom
bbdu3:fix/web-oauth-authorization
Open

bbdu3 wants to merge 1 commit into
modelcontextprotocol:feat-client-authfrom
bbdu3:fix/web-oauth-authorization

Conversation

@bbdu3

@bbdu3 bbdu3 commented Nov 4, 2026 •

Copy link
Copy Markdown

Summary

Support deferred OAuth authorization for web applications, allowing the authorization code flow to resume through a subsequent callback request, including across different PHP workers.

Adds RedirectAuthorizationHandler, AuthorizationPendingException, and OAuthAuthenticator::finishAuthorization(), with persistent, single-use authorization state and regression tests.

Fixes #630.

Motivation and Context

AuthorizationHandlerInterface::authorize() currently expects callback parameters within the same call, which does not fit web applications where authorization redirects and callbacks are handled by separate HTTP requests.

This change implements the approach :

  • The handler throws AuthorizationPendingException with the authorization URL.
  • The authenticator persists the pending flow before propagating the exception.
  • The callback route calls finishAuthorization() to validate the response, exchange the authorization code, and store the tokens.
  • The application can then retry the original MCP operation.

Test

Unit tests

All 54 OAuthAuthenticator tests pass, covering cross-instance completion, PKCE context preservation, state validation and replay prevention, issuer validation, user storage isolation, and offline_access fallback.

Storage tests cover interleaved writes, atomic consumption across instances, issuer-specific cleanup, and malformed records.

HTTP integration tests

All 10 OAuth integration tests pass against local authorization and MCP server fixtures.

The cross-process regression test verifies that:

  • Authorization can be completed in separate PHP processes.
  • Only one competing callback succeeds.
  • The persisted token can access a protected MCP tool.
  • Replayed callbacks are rejected.

Broader checks

  • Full unit suite: 1,742 tests, with the same 5 pre-existing Windows-related failures and 1 skipped test as the baseline. i confirmed these failures are not regression introduced in this PR.
  • PHPStan: same 5 pre-existing errors, no new errors.
  • PHP CS Fixer passes for changed PHP files.
  • git diff --check passes.

Breaking Changes

None. Existing interfaces and synchronous authorization remain compatible.

CredentialStorageInterface is unchanged. Deferred authorization requires:

  • Persistent storage implementing PendingAuthorizationStorageInterface.
  • Catching AuthorizationPendingException and redirecting to its authorization URL.
  • Recreating the authenticator in the callback route with the same configuration and session-scoped storage.
  • Calling finishAuthorization() before retrying the MCP operation.

Types of Changes

  • Bug fix (non-breaking change)
  • New feature (non-breaking change)
  • Documentation update

Signed-off-by: unknown <bbdu3@iflytek.com>
@bbdu3
bbdu3 changed the base branch from main to feat-client-auth November 4, 2026 09:39
@chr-hertel chr-hertel added this to the 1.0.0 milestone Nov 4, 2026
@chr-hertel chr-hertel added Client Issues & PRs related to the Client component auth Issues and PRs related to Authentication / OAuth labels Nov 4, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auth Issues and PRs related to Authentication / OAuth Client Issues & PRs related to the Client component

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Client] Let web applications finish the authorization code flow in a later request

2 participants