[auth] Implement CIMD conformance test (#37)
* add cimd test and negative test * Improve auth-test-no-cimd.ts documentation for clarity Address review feedback: expanded comments to better explain what CIMD is, why this client is non-compliant, and what behavior it's testing. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Remove .js extensions from relative imports tsx doesn't require .js extensions for TypeScript imports. Keeps .js for @modelcontextprotocol/sdk imports as those are external packages. Also improves auth-test-no-cimd.ts documentation for clarity. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Skip auth/basic-cimd test until SDK support lands Waiting on typescript-sdk PR #1127 for CIMD support. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix trailing whitespace in auth-test-no-cimd.ts 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
f087e44bdb
commit
d303013e5d
34 changed files with 301 additions and 110 deletions
|
|
@ -7,10 +7,10 @@ import {
|
|||
UnauthorizedError
|
||||
} from '@modelcontextprotocol/sdk/client/auth.js';
|
||||
import type { FetchLike } from '@modelcontextprotocol/sdk/shared/transport.js';
|
||||
import { withOAuthRetry } from './helpers/withOAuthRetry.js';
|
||||
import { ConformanceOAuthProvider } from './helpers/ConformanceOAuthProvider.js';
|
||||
import { runAsCli } from './helpers/cliRunner.js';
|
||||
import { logger } from './helpers/logger.js';
|
||||
import { withOAuthRetry } from './helpers/withOAuthRetry';
|
||||
import { ConformanceOAuthProvider } from './helpers/ConformanceOAuthProvider';
|
||||
import { runAsCli } from './helpers/cliRunner';
|
||||
import { logger } from './helpers/logger';
|
||||
|
||||
/**
|
||||
* Broken client that always uses root-based PRM discovery.
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ import {
|
|||
UnauthorizedError
|
||||
} from '@modelcontextprotocol/sdk/client/auth.js';
|
||||
import type { FetchLike } from '@modelcontextprotocol/sdk/shared/transport.js';
|
||||
import { withOAuthRetry } from './helpers/withOAuthRetry.js';
|
||||
import { ConformanceOAuthProvider } from './helpers/ConformanceOAuthProvider.js';
|
||||
import { runAsCli } from './helpers/cliRunner.js';
|
||||
import { logger } from './helpers/logger.js';
|
||||
import { withOAuthRetry } from './helpers/withOAuthRetry';
|
||||
import { ConformanceOAuthProvider } from './helpers/ConformanceOAuthProvider';
|
||||
import { runAsCli } from './helpers/cliRunner';
|
||||
import { logger } from './helpers/logger';
|
||||
|
||||
/**
|
||||
* Broken client that only responds to 401, not 403.
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ import {
|
|||
UnauthorizedError
|
||||
} from '@modelcontextprotocol/sdk/client/auth.js';
|
||||
import type { FetchLike } from '@modelcontextprotocol/sdk/shared/transport.js';
|
||||
import { withOAuthRetry } from './helpers/withOAuthRetry.js';
|
||||
import { ConformanceOAuthProvider } from './helpers/ConformanceOAuthProvider.js';
|
||||
import { runAsCli } from './helpers/cliRunner.js';
|
||||
import { logger } from './helpers/logger.js';
|
||||
import { withOAuthRetry } from './helpers/withOAuthRetry';
|
||||
import { ConformanceOAuthProvider } from './helpers/ConformanceOAuthProvider';
|
||||
import { runAsCli } from './helpers/cliRunner';
|
||||
import { logger } from './helpers/logger';
|
||||
|
||||
/**
|
||||
* Broken client that ignores the scope from WWW-Authenticate header.
|
||||
|
|
|
|||
51
examples/clients/typescript/auth-test-no-cimd.ts
Normal file
51
examples/clients/typescript/auth-test-no-cimd.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
||||
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
||||
import { withOAuthRetry } from './helpers/withOAuthRetry';
|
||||
import { runAsCli } from './helpers/cliRunner';
|
||||
import { logger } from './helpers/logger';
|
||||
|
||||
/**
|
||||
* Non-compliant client that doesn't use CIMD (Client ID Metadata Document).
|
||||
*
|
||||
* This client intentionally omits the clientMetadataUrl parameter when the server
|
||||
* advertises client_id_metadata_document_supported=true. A compliant client should
|
||||
* use CIMD when the server supports it, but this client falls back to DCR (Dynamic
|
||||
* Client Registration) instead.
|
||||
*
|
||||
* Used to test that conformance checks detect clients that don't properly
|
||||
* implement CIMD support.
|
||||
*/
|
||||
export async function runClient(serverUrl: string): Promise<void> {
|
||||
const client = new Client(
|
||||
{ name: 'test-auth-client-no-cimd', version: '1.0.0' },
|
||||
{ capabilities: {} }
|
||||
);
|
||||
|
||||
// Non-compliant: omitting clientMetadataUrl causes fallback to DCR
|
||||
// A compliant client would pass a clientMetadataUrl here when the server
|
||||
// advertises client_id_metadata_document_supported=true
|
||||
const oauthFetch = withOAuthRetry(
|
||||
'test-auth-client-no-cimd',
|
||||
new URL(serverUrl)
|
||||
)(fetch);
|
||||
|
||||
const transport = new StreamableHTTPClientTransport(new URL(serverUrl), {
|
||||
fetch: oauthFetch
|
||||
});
|
||||
|
||||
await client.connect(transport);
|
||||
logger.debug('Connected to MCP server (without CIMD)');
|
||||
|
||||
await client.listTools();
|
||||
logger.debug('Successfully listed tools');
|
||||
|
||||
await client.callTool({ name: 'test-tool', arguments: {} });
|
||||
logger.debug('Successfully called tool');
|
||||
|
||||
await transport.close();
|
||||
logger.debug('Connection closed successfully');
|
||||
}
|
||||
|
||||
runAsCli(runClient, import.meta.url, 'auth-test-no-cimd <server-url>');
|
||||
|
|
@ -8,10 +8,10 @@ import {
|
|||
UnauthorizedError
|
||||
} from '@modelcontextprotocol/sdk/client/auth.js';
|
||||
import type { FetchLike } from '@modelcontextprotocol/sdk/shared/transport.js';
|
||||
import { withOAuthRetry } from './helpers/withOAuthRetry.js';
|
||||
import { ConformanceOAuthProvider } from './helpers/ConformanceOAuthProvider.js';
|
||||
import { runAsCli } from './helpers/cliRunner.js';
|
||||
import { logger } from './helpers/logger.js';
|
||||
import { withOAuthRetry } from './helpers/withOAuthRetry';
|
||||
import { ConformanceOAuthProvider } from './helpers/ConformanceOAuthProvider';
|
||||
import { runAsCli } from './helpers/cliRunner';
|
||||
import { logger } from './helpers/logger';
|
||||
|
||||
/**
|
||||
* Broken client that only requests a subset of scopes.
|
||||
|
|
|
|||
|
|
@ -2,9 +2,17 @@
|
|||
|
||||
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
||||
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
||||
import { withOAuthRetry } from './helpers/withOAuthRetry.js';
|
||||
import { runAsCli } from './helpers/cliRunner.js';
|
||||
import { logger } from './helpers/logger.js';
|
||||
import { withOAuthRetry, handle401 } from './helpers/withOAuthRetry';
|
||||
import { runAsCli } from './helpers/cliRunner';
|
||||
import { logger } from './helpers/logger';
|
||||
|
||||
/**
|
||||
* Fixed client metadata URL for CIMD conformance tests.
|
||||
* When server supports client_id_metadata_document_supported, this URL
|
||||
* will be used as the client_id instead of doing dynamic registration.
|
||||
*/
|
||||
const CIMD_CLIENT_METADATA_URL =
|
||||
'https://conformance-test.local/client-metadata.json';
|
||||
|
||||
/**
|
||||
* Well-behaved auth client that follows all OAuth protocols correctly.
|
||||
|
|
@ -17,7 +25,9 @@ export async function runClient(serverUrl: string): Promise<void> {
|
|||
|
||||
const oauthFetch = withOAuthRetry(
|
||||
'test-auth-client',
|
||||
new URL(serverUrl)
|
||||
new URL(serverUrl),
|
||||
handle401,
|
||||
CIMD_CLIENT_METADATA_URL
|
||||
)(fetch);
|
||||
|
||||
const transport = new StreamableHTTPClientTransport(new URL(serverUrl), {
|
||||
|
|
|
|||
|
|
@ -27,13 +27,11 @@ export class ConformanceOAuthProvider implements OAuthClientProvider {
|
|||
return this._clientMetadata;
|
||||
}
|
||||
|
||||
get clientMetadataUrl(): string | undefined {
|
||||
return this._clientMetadataUrl?.toString();
|
||||
}
|
||||
|
||||
clientInformation(): OAuthClientInformation | undefined {
|
||||
if (this._clientMetadataUrl) {
|
||||
console.log('Using client ID metadata URL');
|
||||
return {
|
||||
client_id: this._clientMetadataUrl.toString()
|
||||
};
|
||||
}
|
||||
return this._clientInformation;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,14 +60,16 @@ export const handle401 = async (
|
|||
export const withOAuthRetry = (
|
||||
clientName: string,
|
||||
baseUrl?: string | URL,
|
||||
handle401Fn: typeof handle401 = handle401
|
||||
handle401Fn: typeof handle401 = handle401,
|
||||
clientMetadataUrl?: string
|
||||
): Middleware => {
|
||||
const provider = new ConformanceOAuthProvider(
|
||||
'http://localhost:3000/callback',
|
||||
{
|
||||
client_name: clientName,
|
||||
redirect_uris: ['http://localhost:3000/callback']
|
||||
}
|
||||
},
|
||||
clientMetadataUrl
|
||||
);
|
||||
return (next: FetchLike) => {
|
||||
return async (
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { ConformanceCheck, CheckStatus } from '../types.js';
|
||||
import { ConformanceCheck, CheckStatus } from '../types';
|
||||
|
||||
export function createServerInfoCheck(serverInfo: {
|
||||
name: string;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Namespaced exports for client checks
|
||||
import * as client from './client.js';
|
||||
import * as client from './client';
|
||||
|
||||
export const clientChecks = client;
|
||||
|
|
|
|||
99
src/scenarios/client/auth/basic-cimd.ts
Normal file
99
src/scenarios/client/auth/basic-cimd.ts
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
import type { Scenario, ConformanceCheck } from '../../../types';
|
||||
import { ScenarioUrls } from '../../../types';
|
||||
import { createAuthServer } from './helpers/createAuthServer';
|
||||
import { createServer } from './helpers/createServer';
|
||||
import { ServerLifecycle } from './helpers/serverLifecycle';
|
||||
import { SpecReferences } from './spec-references';
|
||||
|
||||
/**
|
||||
* Fixed client metadata URL that clients should use for CIMD tests.
|
||||
* This URL doesn't need to resolve - the server will accept it as-is
|
||||
* and use hardcoded metadata.
|
||||
*/
|
||||
export const CIMD_CLIENT_METADATA_URL =
|
||||
'https://conformance-test.local/client-metadata.json';
|
||||
|
||||
/**
|
||||
* Scenario: Client ID Metadata Documents (SEP-991/URL-based client IDs)
|
||||
*
|
||||
* Tests that when a server advertises client_id_metadata_document_supported=true,
|
||||
* clients SHOULD use a URL as their client_id instead of using dynamic client
|
||||
* registration.
|
||||
*/
|
||||
export class AuthBasicCIMDScenario implements Scenario {
|
||||
name = 'auth/basic-cimd';
|
||||
description =
|
||||
'Tests OAuth flow with Client ID Metadata Documents (SEP-991/URL-based client IDs). Server advertises client_id_metadata_document_supported=true and client should use URL as client_id instead of DCR.';
|
||||
private authServer = new ServerLifecycle();
|
||||
private server = new ServerLifecycle();
|
||||
private checks: ConformanceCheck[] = [];
|
||||
|
||||
async start(): Promise<ScenarioUrls> {
|
||||
this.checks = [];
|
||||
|
||||
const authApp = createAuthServer(this.checks, this.authServer.getUrl, {
|
||||
clientIdMetadataDocumentSupported: true,
|
||||
onAuthorizationRequest: (data) => {
|
||||
// Check if client used URL-based client ID
|
||||
const usedUrlClientId = data.clientId === CIMD_CLIENT_METADATA_URL;
|
||||
this.checks.push({
|
||||
id: 'cimd-client-id-used',
|
||||
name: 'Client ID Metadata Document Usage',
|
||||
description: usedUrlClientId
|
||||
? 'Client correctly used URL-based client ID when server supports client_id_metadata_document_supported'
|
||||
: 'Client SHOULD use URL-based client ID when server advertises client_id_metadata_document_supported=true',
|
||||
status: usedUrlClientId ? 'SUCCESS' : 'WARNING',
|
||||
timestamp: data.timestamp,
|
||||
specReferences: [
|
||||
SpecReferences.MCP_CLIENT_ID_METADATA_DOCUMENTS,
|
||||
SpecReferences.IETF_CIMD
|
||||
],
|
||||
details: {
|
||||
expectedClientId: CIMD_CLIENT_METADATA_URL,
|
||||
actualClientId: data.clientId || 'none'
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
await this.authServer.start(authApp);
|
||||
|
||||
const app = createServer(
|
||||
this.checks,
|
||||
this.server.getUrl,
|
||||
this.authServer.getUrl
|
||||
);
|
||||
|
||||
await this.server.start(app);
|
||||
|
||||
return { serverUrl: `${this.server.getUrl()}/mcp` };
|
||||
}
|
||||
|
||||
async stop() {
|
||||
await this.authServer.stop();
|
||||
await this.server.stop();
|
||||
}
|
||||
|
||||
getChecks(): ConformanceCheck[] {
|
||||
// Ensure we have the CIMD check - if not, the client didn't make an auth request
|
||||
const hasCimdCheck = this.checks.some(
|
||||
(c) => c.id === 'cimd-client-id-used'
|
||||
);
|
||||
if (!hasCimdCheck) {
|
||||
this.checks.push({
|
||||
id: 'cimd-client-id-used',
|
||||
name: 'Client ID Metadata Document Usage',
|
||||
description:
|
||||
'Client did not make an authorization request to test CIMD support',
|
||||
status: 'FAILURE',
|
||||
timestamp: new Date().toISOString(),
|
||||
specReferences: [
|
||||
SpecReferences.MCP_CLIENT_ID_METADATA_DOCUMENTS,
|
||||
SpecReferences.IETF_CIMD
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
return this.checks;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,12 +6,12 @@
|
|||
* generated from them.
|
||||
*/
|
||||
|
||||
import type { Scenario, ConformanceCheck } from '../../../types.js';
|
||||
import { ScenarioUrls } from '../../../types.js';
|
||||
import { createAuthServer } from './helpers/createAuthServer.js';
|
||||
import { createServer } from './helpers/createServer.js';
|
||||
import { ServerLifecycle } from './helpers/serverLifecycle.js';
|
||||
import { SpecReferences } from './spec-references.js';
|
||||
import type { Scenario, ConformanceCheck } from '../../../types';
|
||||
import { ScenarioUrls } from '../../../types';
|
||||
import { createAuthServer } from './helpers/createAuthServer';
|
||||
import { createServer } from './helpers/createServer';
|
||||
import { ServerLifecycle } from './helpers/serverLifecycle';
|
||||
import { SpecReferences } from './spec-references';
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import express, { Request, Response } from 'express';
|
||||
import type { ConformanceCheck } from '../../../../types.js';
|
||||
import { createRequestLogger } from '../../../request-logger.js';
|
||||
import { SpecReferences } from '../spec-references.js';
|
||||
import { MockTokenVerifier } from './mockTokenVerifier.js';
|
||||
import type { ConformanceCheck } from '../../../../types';
|
||||
import { createRequestLogger } from '../../../request-logger';
|
||||
import { SpecReferences } from '../spec-references';
|
||||
import { MockTokenVerifier } from './mockTokenVerifier';
|
||||
|
||||
export interface AuthServerOptions {
|
||||
metadataPath?: string;
|
||||
|
|
@ -10,6 +10,7 @@ export interface AuthServerOptions {
|
|||
loggingEnabled?: boolean;
|
||||
routePrefix?: string;
|
||||
scopesSupported?: string[];
|
||||
clientIdMetadataDocumentSupported?: boolean;
|
||||
tokenVerifier?: MockTokenVerifier;
|
||||
onTokenRequest?: (requestData: {
|
||||
scope?: string;
|
||||
|
|
@ -17,6 +18,7 @@ export interface AuthServerOptions {
|
|||
timestamp: string;
|
||||
}) => { token: string; scopes: string[] };
|
||||
onAuthorizationRequest?: (requestData: {
|
||||
clientId?: string;
|
||||
scope?: string;
|
||||
timestamp: string;
|
||||
}) => void;
|
||||
|
|
@ -33,6 +35,7 @@ export function createAuthServer(
|
|||
loggingEnabled = true,
|
||||
routePrefix = '',
|
||||
scopesSupported,
|
||||
clientIdMetadataDocumentSupported,
|
||||
tokenVerifier,
|
||||
onTokenRequest,
|
||||
onAuthorizationRequest
|
||||
|
|
@ -93,6 +96,12 @@ export function createAuthServer(
|
|||
metadata.scopes_supported = scopesSupported;
|
||||
}
|
||||
|
||||
// Add client_id_metadata_document_supported if provided
|
||||
if (clientIdMetadataDocumentSupported !== undefined) {
|
||||
metadata.client_id_metadata_document_supported =
|
||||
clientIdMetadataDocumentSupported;
|
||||
}
|
||||
|
||||
// Add OpenID Configuration specific fields
|
||||
if (isOpenIdConfiguration) {
|
||||
metadata.jwks_uri = `${getAuthBaseUrl()}/.well-known/jwks.json`;
|
||||
|
|
@ -123,6 +132,7 @@ export function createAuthServer(
|
|||
|
||||
if (onAuthorizationRequest) {
|
||||
onAuthorizationRequest({
|
||||
clientId: req.query.client_id as string | undefined,
|
||||
scope: scopeParam,
|
||||
timestamp
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ import {
|
|||
} from '@modelcontextprotocol/sdk/types.js';
|
||||
import { requireBearerAuth } from '@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js';
|
||||
import express, { Request, Response, NextFunction } from 'express';
|
||||
import type { ConformanceCheck } from '../../../../types.js';
|
||||
import { createRequestLogger } from '../../../request-logger.js';
|
||||
import { MockTokenVerifier } from './mockTokenVerifier.js';
|
||||
import { SpecReferences } from '../spec-references.js';
|
||||
import type { ConformanceCheck } from '../../../../types';
|
||||
import { createRequestLogger } from '../../../request-logger';
|
||||
import { MockTokenVerifier } from './mockTokenVerifier';
|
||||
import { SpecReferences } from '../spec-references';
|
||||
|
||||
export interface ServerOptions {
|
||||
prmPath?: string | null;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { OAuthTokenVerifier } from '@modelcontextprotocol/sdk/server/auth/provider.js';
|
||||
import { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
|
||||
import type { ConformanceCheck } from '../../../../types.js';
|
||||
import { SpecReferences } from '../spec-references.js';
|
||||
import type { ConformanceCheck } from '../../../../types';
|
||||
import { SpecReferences } from '../spec-references';
|
||||
|
||||
export class MockTokenVerifier implements OAuthTokenVerifier {
|
||||
private tokenScopes: Map<string, string[]> = new Map();
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
import { authScenariosList } from './index.js';
|
||||
import { authScenariosList } from './index';
|
||||
import {
|
||||
runClientAgainstScenario,
|
||||
InlineClientRunner
|
||||
} from './test_helpers/testClient.js';
|
||||
import { runClient as goodClient } from '../../../../examples/clients/typescript/auth-test.js';
|
||||
import { runClient as badPrmClient } from '../../../../examples/clients/typescript/auth-test-bad-prm.js';
|
||||
import { runClient as ignoreScopeClient } from '../../../../examples/clients/typescript/auth-test-ignore-scope.js';
|
||||
import { runClient as partialScopesClient } from '../../../../examples/clients/typescript/auth-test-partial-scopes.js';
|
||||
import { runClient as ignore403Client } from '../../../../examples/clients/typescript/auth-test-ignore-403.js';
|
||||
import { setLogLevel } from '../../../../examples/clients/typescript/helpers/logger.js';
|
||||
} from './test_helpers/testClient';
|
||||
import { runClient as goodClient } from '../../../../examples/clients/typescript/auth-test';
|
||||
import { runClient as badPrmClient } from '../../../../examples/clients/typescript/auth-test-bad-prm';
|
||||
import { runClient as noCimdClient } from '../../../../examples/clients/typescript/auth-test-no-cimd';
|
||||
import { runClient as ignoreScopeClient } from '../../../../examples/clients/typescript/auth-test-ignore-scope';
|
||||
import { runClient as partialScopesClient } from '../../../../examples/clients/typescript/auth-test-partial-scopes';
|
||||
import { runClient as ignore403Client } from '../../../../examples/clients/typescript/auth-test-ignore-403';
|
||||
import { setLogLevel } from '../../../../examples/clients/typescript/helpers/logger';
|
||||
|
||||
beforeAll(() => {
|
||||
setLogLevel('error');
|
||||
|
|
@ -22,7 +23,10 @@ const skipScenarios = new Set<string>([
|
|||
// Waiting on typescript-sdk support for using scopes_supported from PRM
|
||||
// to request scopes.
|
||||
// https://github.com/modelcontextprotocol/typescript-sdk/pull/1133
|
||||
'auth/scope-from-scopes-supported'
|
||||
'auth/scope-from-scopes-supported',
|
||||
// Waiting on typescript-sdk support for CIMD
|
||||
// https://github.com/modelcontextprotocol/typescript-sdk/pull/1127
|
||||
'auth/basic-cimd'
|
||||
]);
|
||||
|
||||
describe('Client Auth Scenarios', () => {
|
||||
|
|
@ -76,4 +80,11 @@ describe('Negative tests', () => {
|
|||
'scope-step-up-escalation'
|
||||
]);
|
||||
});
|
||||
|
||||
test('client uses DCR instead of CIMD when server supports it', async () => {
|
||||
const runner = new InlineClientRunner(noCimdClient);
|
||||
await runClientAgainstScenario(runner, 'auth/basic-cimd', [
|
||||
'cimd-client-id-used'
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
import { Scenario } from '../../../types';
|
||||
import { metadataScenarios } from './discovery-metadata.js';
|
||||
import { metadataScenarios } from './discovery-metadata';
|
||||
import { AuthBasicCIMDScenario } from './basic-cimd';
|
||||
import {
|
||||
Auth20250326OAuthMetadataBackcompatScenario,
|
||||
Auth20250326OEndpointFallbackScenario
|
||||
} from './march-spec-backcompat.js';
|
||||
} from './march-spec-backcompat';
|
||||
import {
|
||||
ScopeFromWwwAuthenticateScenario,
|
||||
ScopeFromScopesSupportedScenario,
|
||||
ScopeOmittedWhenUndefinedScenario,
|
||||
ScopeStepUpAuthScenario
|
||||
} from './scope-handling.js';
|
||||
} from './scope-handling';
|
||||
|
||||
export const authScenariosList: Scenario[] = [
|
||||
...metadataScenarios,
|
||||
new AuthBasicCIMDScenario(),
|
||||
new Auth20250326OAuthMetadataBackcompatScenario(),
|
||||
new Auth20250326OEndpointFallbackScenario(),
|
||||
new ScopeFromWwwAuthenticateScenario(),
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import type { Scenario, ConformanceCheck } from '../../../types.js';
|
||||
import { ScenarioUrls } from '../../../types.js';
|
||||
import { createAuthServer } from './helpers/createAuthServer.js';
|
||||
import { createServer } from './helpers/createServer.js';
|
||||
import { ServerLifecycle } from './helpers/serverLifecycle.js';
|
||||
import type { Scenario, ConformanceCheck } from '../../../types';
|
||||
import { ScenarioUrls } from '../../../types';
|
||||
import { createAuthServer } from './helpers/createAuthServer';
|
||||
import { createServer } from './helpers/createServer';
|
||||
import { ServerLifecycle } from './helpers/serverLifecycle';
|
||||
import express, { Request, Response } from 'express';
|
||||
import { SpecReferences } from './spec-references.js';
|
||||
import { SpecReferences } from './spec-references';
|
||||
|
||||
export class Auth20250326OAuthMetadataBackcompatScenario implements Scenario {
|
||||
name = 'auth/2025-03-26-oauth-metadata-backcompat';
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import type { Scenario, ConformanceCheck } from '../../../types.js';
|
||||
import { ScenarioUrls } from '../../../types.js';
|
||||
import { createAuthServer } from './helpers/createAuthServer.js';
|
||||
import { createServer } from './helpers/createServer.js';
|
||||
import { ServerLifecycle } from './helpers/serverLifecycle.js';
|
||||
import { SpecReferences } from './spec-references.js';
|
||||
import { MockTokenVerifier } from './helpers/mockTokenVerifier.js';
|
||||
import type { Scenario, ConformanceCheck } from '../../../types';
|
||||
import { ScenarioUrls } from '../../../types';
|
||||
import { createAuthServer } from './helpers/createAuthServer';
|
||||
import { createServer } from './helpers/createServer';
|
||||
import { ServerLifecycle } from './helpers/serverLifecycle';
|
||||
import { SpecReferences } from './spec-references';
|
||||
import { MockTokenVerifier } from './helpers/mockTokenVerifier';
|
||||
import type { Request, Response, NextFunction } from 'express';
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -52,5 +52,13 @@ export const SpecReferences: { [key: string]: SpecReference } = {
|
|||
MCP_AUTH_ERROR_HANDLING: {
|
||||
id: 'MCP-Auth-error-handling',
|
||||
url: 'https://modelcontextprotocol.io/specification/draft/basic/authorization#error-handling'
|
||||
},
|
||||
MCP_CLIENT_ID_METADATA_DOCUMENTS: {
|
||||
id: 'MCP-Client-ID-Metadata-Documents',
|
||||
url: 'https://modelcontextprotocol.io/specification/draft/basic/authorization#client-id-metadata-documents'
|
||||
},
|
||||
IETF_CIMD: {
|
||||
id: 'IETF-OAuth-Client-ID-Metadata-Document',
|
||||
url: 'https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-00'
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue