adjust default validation for resource parameter in client flow, and server example

This commit is contained in:
Paul Carleton 2025-06-19 17:52:24 +01:00
commit 87da0e0c3a
No known key found for this signature in database
2 changed files with 85 additions and 13 deletions

View file

@ -1041,7 +1041,7 @@ describe("OAuth Authorization", () => {
// Verify custom validation method was called
expect(mockValidateResourceURL).toHaveBeenCalledWith(
"https://api.example.com/mcp-server",
new URL("https://api.example.com/mcp-server"),
"https://different-resource.example.com/mcp-server"
);
});

View file

@ -2,7 +2,7 @@ import pkceChallenge from "pkce-challenge";
import { LATEST_PROTOCOL_VERSION } from "../types.js";
import type { OAuthClientMetadata, OAuthClientInformation, OAuthTokens, OAuthMetadata, OAuthClientInformationFull, OAuthProtectedResourceMetadata } from "../shared/auth.js";
import { OAuthClientInformationFullSchema, OAuthMetadataSchema, OAuthProtectedResourceMetadataSchema, OAuthTokensSchema } from "../shared/auth.js";
import { resourceUrlFromServerUrl } from "../shared/auth-utils.js";
import { checkResourceAllowed, resourceUrlFromServerUrl } from "../shared/auth-utils.js";
/**
* Implements an end-to-end OAuth client to be used with one MCP server.
@ -198,13 +198,13 @@ export async function auth(
}
async function selectResourceURL(serverUrl: string| URL, provider: OAuthClientProvider, resourceMetadata?: OAuthProtectedResourceMetadata): Promise<URL | undefined> {
const resource = resourceUrlFromServerUrl(serverUrl);
if (provider.validateResourceURL) {
return await provider.validateResourceURL(serverUrl, resourceMetadata?.resource);
}
const resource = resourceUrlFromServerUrl(typeof serverUrl === "string" ? new URL(serverUrl) : serverUrl);
if (resourceMetadata && resourceMetadata.resource !== resource.href) {
throw new Error(`Protected resource ${resourceMetadata.resource} does not match expected ${resource}`);
return await provider.validateResourceURL(resource, resourceMetadata?.resource);
} else if (resourceMetadata) {
if (!checkResourceAllowed({ requestedResource: resource, configuredResource: resourceMetadata.resource })) {
throw new Error(`Protected resource ${resourceMetadata.resource} does not match expected ${resource} (or origin)`);
}
}
return resource;