Add a conceptual guide for production OAuth authorization - #1801
Open
anneheartrecord wants to merge 1 commit into
Open
Add a conceptual guide for production OAuth authorization#1801anneheartrecord wants to merge 1 commit into
anneheartrecord wants to merge 1 commit into
Conversation
Documents how to protect an MCP server with OAuth 2.0 against an existing identity provider, rather than standing up an authorization server the way the TestOAuthServer fixture does. Covers the resource server / authorization server split, what to require of an authorization server, JwtBearer plus AddMcp configuration, protected resource metadata behind a reverse proxy, per-request metadata for multi-tenant servers, endpoint and per-primitive enforcement with AddAuthorizationFilters, scope-based policies, and how claims are refreshed relative to sessions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #1052
PR Summary
Adds a conceptual guide covering how to do OAuth for a real deployment, so that the answer to "how should someone building a real world MCP server go about authentication?" isn't "read the test fixture."
The core confusion in #1052 is that
TestOAuthServerlooks like the thing you're supposed to build. It isn't — it's an authorization server, and an MCP server is a resource server. Once that split is clear, the production configuration is mostlyAddJwtBearerpointed at an identity provider you already run, plusAddMcp()for the RFC 9728 metadata. The guide leads with that and then covers the parts that actually bite in production.What's included
docs/concepts/authorization/authorization.mddocs/concepts/toc.yml(under Server features, next to HTTP Context)docs/concepts/index.mdGuide coverage
TestOAuthServeris a fixture rather than a templateAddJwtBearer+AddMcpconfiguration, with audience validation tied to the advertised resourceResourcemust be set explicitly, and the reverse-proxy case — the resource identifier and theresource_metadatachallenge URL are both derived from the request, so forwarded headers (includingX-Forwarded-Prefix, andAllowedHoststo keep them un-spoofable) matterOnResourceMetadataRequestfor multi-tenant serversRequireAuthorization()on the endpoint, and[Authorize]/[AllowAnonymous]per primitive viaAddAuthorizationFilters()— including that listings are filtered, that custom list handlers are not, and that[AllowAnonymous]doesn't combine with endpoint-level gatingRequireClaim("scope", ...)is the wrong tool for a space-delimited claim[Authorize]checks re-read the principal per request, whileConfigureSessionOptionsis once per sessionNotes
McpAuthenticationHandler,McpAuthenticationOptions,ProtectedResourceMetadata,AuthorizationFilterSetup,HttpMcpServerBuilderExtensions, andAuthorizeAttributeTests.make generate-docslocally (no .NET SDK on this machine), so the DocFX build is unverified. The three<xref:>API targets and thexref:identity/xref:stateless/xref:httpcontextlinks were checked by hand against the source and the sibling docs' uids, and theuid: authorizationis unique. Worth a second look from CI.