Merge pull request #664 from modelcontextprotocol/pcarleton/auth-resource-validation2
[auth] adjust default validation for resource parameter in client flow, and server example
This commit is contained in:
commit
66b7cd2642
1 changed files with 150 additions and 14 deletions
|
|
@ -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.
|
||||
|
|
@ -197,14 +197,17 @@ export async function auth(
|
|||
return "REDIRECT";
|
||||
}
|
||||
|
||||
async function selectResourceURL(serverUrl: string| URL, provider: OAuthClientProvider, resourceMetadata?: OAuthProtectedResourceMetadata): Promise<URL | undefined> {
|
||||
export async function selectResourceURL(serverUrl: string| URL, provider: OAuthClientProvider, resourceMetadata?: OAuthProtectedResourceMetadata): Promise<URL | undefined> {
|
||||
let 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 })) {
|
||||
// If the resource mentioned in metadata is valid, prefer it since it is what the server is telling us to request.
|
||||
resource = new URL(resourceMetadata.resource);
|
||||
} else {
|
||||
throw new Error(`Protected resource ${resourceMetadata.resource} does not match expected ${resource} (or origin)`);
|
||||
}
|
||||
}
|
||||
|
||||
return resource;
|
||||
|
|
|
|||
Loading…
Reference in a new issue