modelcontextprotocol/typescript-sdk

Prefer token endpoint auth method obtained during OAuth client registration

Opened this issue · 2 comments

Describe the bug
When doing an OAuth flow using dynamic client registration, the token_endpoint_auth_method returned in the registration data should be used to request a token, rather than the one from the OAuth authorization server metadata. Not doing this may cause an OAuth flow to fail if a strict server requires the method that was posted and used during client registration.

To Reproduce
Steps to reproduce the behavior:

  1. Use the code from the sample client (src/examples/client/simpleOAuthClient.ts) which specifies token_endpoint_auth_method: 'client_secret_post' in the OAuthClientMetadata.
  2. The client will register using client_secret_post, and we assume that the server will confirm that in the registration response.
  3. In exchangeAuthorization and in refreshAuthorization (src/client/auth.ts), the following code is used:
    // Determine and apply client authentication method
    const supportedMethods = metadata?.token_endpoint_auth_methods_supported ?? [];
    const authMethod = selectClientAuthMethod(clientInformation, supportedMethods);

    applyClientAuthentication(authMethod, clientInformation, headers, params);

and selectClientAuthMethod uses this check which takes the supported methods from the OAuth authorization server metadata, rather than the clientInformation:

  if (hasClientSecret && supportedMethods.includes("client_secret_basic")) {
    return "client_secret_basic";
  }
  1. Server may reject the token response due to client_secret_basic being used rather than client_secret_post since the server may not need to honor client_secret_basic anymore after the client was registered with client_secret_post.

Expected behavior
Prefer the token_endpoint_auth_method from the client clientInformation that was obtained during registration, and only if it's unavailable fall back to the metadata from the OAuth authorization server.

@thomasst I attempted a fix for this if you would like to try it out and confirm it works #982

Hitting this as well with our OAuth2 server. We always issue a client_secret, even if the token_endpoint_auth_method is set to none. MCP then tries to authenticate with a client_secret_basic method, but we reject it since the client expects none.