Add IncludeResourceIndicator option for OAuth and DI client sample#1402
Add IncludeResourceIndicator option for OAuth and DI client sample#1402Varun6578 wants to merge 2 commits intomodelcontextprotocol:mainfrom
Conversation
Fix modelcontextprotocol#648: Add IncludeResourceIndicator option to ClientOAuthOptions to allow suppressing the RFC 8707 'resource' parameter in OAuth requests. This enables compatibility with OAuth providers like MS Entra-ID (Azure AD v2.0) that do not support the resource parameter. Fix modelcontextprotocol#147: Add DependencyInjectionClient sample project demonstrating how to wire up MCP clients with Microsoft.Extensions.DependencyInjection and IHostedService. Add DI guidance section to getting-started docs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…doc warning - GetAccessTokenSilentAsync now omits the resource parameter from token refresh requests when IncludeResourceIndicator is false, matching the behavior of the 401 handler and authorization URL paths. - Added warning comment in getting-started.md about .GetAwaiter().GetResult() deadlock risk in SynchronizationContext environments. - Added end-to-end tests with mock Entra ID server (ExpectResource=false) validating full auth flow and token refresh without resource parameter. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
5819a96 to
b653294
Compare
| /// which returns error <c>AADSTS901002</c> when the parameter is present. | ||
| /// </para> | ||
| /// </remarks> | ||
| public bool IncludeResourceIndicator { get; set; } = true; |
There was a problem hiding this comment.
Configuring this to false is insecure for MCP apps. We're required by the spec to send the resource parameter because of this.
See #940 (comment) for more context.
MCP servers are different than most HTTP servers using OAuth authorization code flow that can rely on TLS and limiting redirect URIs to ensure authorization codes and ultimately access tokens don't get sent to the wrong HTTP server (which is the OAuth client in the scenario). MCP uses the authorization code flow to send the authorization code to a non-first-party, non-browser client. Without a resource parameter, neither Entra nor any other OAuth server have any way to validate that the token will be sent to the expected MCP server. And your MCP server has no way to validate that the access token was sent directly to it rather than main-in-the-middled (MITM'd).
The lack of a resource parameter would make it trivial for another MCP server to copy your Protected Resource Metadata document and then MITM your MCP server. All the attacker would need to do is convince someone to enter the wrong URL into their MCP config while protending to be your server. The end-user's browser will happily autofill their credentials as they go to the real OAuth provider's website even though the resulting access token will ultimately be sent to the attackers MCP server first by the non-conforming MCP client that does not send the resource parameter.
Summary
This PR addresses two issues from the Backlog milestone:
Fix #648: OAuth authentication fails with MS Entra-ID
The SDK sends a
resourceparameter (RFC 8707) in OAuth authorization, token exchange, and token refresh requests. MS Entra-ID v2.0 does not support this parameter and returnsAADSTS901002.Changes:
IncludeResourceIndicatorproperty toClientOAuthOptions(defaults totruefor backward compatibility)false, theresourceparameter is omitted from all OAuth requestsresourceparameter when the option is disabledUsage:
Fix #147: Add client sample with DI guidance
samples/DependencyInjectionClientshowing how to registerMcpClientas a singleton viaIServiceCollectionand consume it from anIHostedServicedocs/concepts/getting-started.mdTesting
CanAuthenticate_WithoutResourceIndicatorvalidates the feature