fix(auth): make 2025-03-26 backcompat mock RFC 8414 §3.3-compliant (#359)
* fix(auth): make 2025-03-26 backcompat mock RFC 8414 §3.3-compliant Drop the routePrefix from auth/2025-03-26-oauth-metadata-backcompat. The prefix caused createAuthServer to report issuer:'<origin>/oauth' while serving the metadata at the root /.well-known/oauth-authorization-server — an RFC 8414 §3.3 mismatch a conforming client must reject. The MCP server in this scenario only mounts /mcp, so the unprefixed /authorize, /token, /register routes do not collide (the sibling endpoint-fallback scenario already mounts them at root). The scenario continues to test exactly what it's meant to: 2025-03-26-spec discovery with no PRM, OAuth metadata at the root well-known path. * fix(auth): keep /oauth prefix in 2025-03-26 backcompat, override issuer instead Dropping routePrefix made the metadata-advertised endpoints land on the 2025-03-26 hardcoded fallback paths, so a client that fetches the well-known doc but ignores its body would now pass. Restore the prefix and pin the metadata issuer to the bare origin via a lazy metadataIssuer override so the mock is RFC 8414 §3.3-compliant without losing the fallback-vs-metadata distinction. --------- Co-authored-by: Paul Carleton <paulc@anthropic.com>
This commit is contained in:
parent
bb11cff348
commit
af6489593e
2 changed files with 13 additions and 4 deletions
|
|
@ -59,8 +59,10 @@ export interface AuthServerOptions {
|
|||
* Override the `issuer` value served in the AS metadata document. Used to
|
||||
* test that clients validate the metadata issuer against the issuer
|
||||
* identifier used to construct the well-known URL (RFC 8414 §3.3).
|
||||
* Accepts a lazy getter for callers that don't know the server URL until
|
||||
* after `start()`.
|
||||
*/
|
||||
metadataIssuer?: string;
|
||||
metadataIssuer?: string | (() => string);
|
||||
tokenVerifier?: MockTokenVerifier;
|
||||
onTokenRequest?: (requestData: {
|
||||
scope?: string;
|
||||
|
|
@ -156,7 +158,10 @@ export function createAuthServer(
|
|||
});
|
||||
|
||||
const metadata: any = {
|
||||
issuer: metadataIssuer ?? `${getAuthBaseUrl()}${routePrefix}`,
|
||||
issuer:
|
||||
typeof metadataIssuer === 'function'
|
||||
? metadataIssuer()
|
||||
: (metadataIssuer ?? `${getAuthBaseUrl()}${routePrefix}`),
|
||||
authorization_endpoint: `${getAuthBaseUrl()}${authRoutes.authorization_endpoint}`,
|
||||
token_endpoint: `${getAuthBaseUrl()}${authRoutes.token_endpoint}`,
|
||||
...(!disableDynamicRegistration && {
|
||||
|
|
|
|||
|
|
@ -25,8 +25,12 @@ export class Auth20250326OAuthMetadataBackcompatScenario implements Scenario {
|
|||
const authApp = createAuthServer(ctx, this.checks, this.server.getUrl, {
|
||||
// Disable logging since the main server will already have logging enabled
|
||||
loggingEnabled: false,
|
||||
// Add a prefix to auth endpoints to avoid being caught by auth fallbacks
|
||||
routePrefix: '/oauth'
|
||||
// Keep auth endpoints off the 2025-03-26 fallback paths so a client that
|
||||
// fetches metadata but ignores the advertised endpoints still 404s.
|
||||
routePrefix: '/oauth',
|
||||
// Metadata is served at the root well-known path, so per RFC 8414 §3.3
|
||||
// the `issuer` must be the bare origin — not `<origin>/oauth`.
|
||||
metadataIssuer: () => this.server.getUrl()
|
||||
});
|
||||
const app = createServer(
|
||||
ctx,
|
||||
|
|
|
|||
Loading…
Reference in a new issue