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
|
* Override the `issuer` value served in the AS metadata document. Used to
|
||||||
* test that clients validate the metadata issuer against the issuer
|
* test that clients validate the metadata issuer against the issuer
|
||||||
* identifier used to construct the well-known URL (RFC 8414 §3.3).
|
* 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;
|
tokenVerifier?: MockTokenVerifier;
|
||||||
onTokenRequest?: (requestData: {
|
onTokenRequest?: (requestData: {
|
||||||
scope?: string;
|
scope?: string;
|
||||||
|
|
@ -156,7 +158,10 @@ export function createAuthServer(
|
||||||
});
|
});
|
||||||
|
|
||||||
const metadata: any = {
|
const metadata: any = {
|
||||||
issuer: metadataIssuer ?? `${getAuthBaseUrl()}${routePrefix}`,
|
issuer:
|
||||||
|
typeof metadataIssuer === 'function'
|
||||||
|
? metadataIssuer()
|
||||||
|
: (metadataIssuer ?? `${getAuthBaseUrl()}${routePrefix}`),
|
||||||
authorization_endpoint: `${getAuthBaseUrl()}${authRoutes.authorization_endpoint}`,
|
authorization_endpoint: `${getAuthBaseUrl()}${authRoutes.authorization_endpoint}`,
|
||||||
token_endpoint: `${getAuthBaseUrl()}${authRoutes.token_endpoint}`,
|
token_endpoint: `${getAuthBaseUrl()}${authRoutes.token_endpoint}`,
|
||||||
...(!disableDynamicRegistration && {
|
...(!disableDynamicRegistration && {
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,12 @@ export class Auth20250326OAuthMetadataBackcompatScenario implements Scenario {
|
||||||
const authApp = createAuthServer(ctx, this.checks, this.server.getUrl, {
|
const authApp = createAuthServer(ctx, this.checks, this.server.getUrl, {
|
||||||
// Disable logging since the main server will already have logging enabled
|
// Disable logging since the main server will already have logging enabled
|
||||||
loggingEnabled: false,
|
loggingEnabled: false,
|
||||||
// Add a prefix to auth endpoints to avoid being caught by auth fallbacks
|
// Keep auth endpoints off the 2025-03-26 fallback paths so a client that
|
||||||
routePrefix: '/oauth'
|
// 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(
|
const app = createServer(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue