Skip to content

Commit e55037e

Browse files
committed
simplify verifier, and fix router test
1 parent 8acd5ed commit e55037e

File tree

3 files changed

+107
-137
lines changed

3 files changed

+107
-137
lines changed

src/examples/server/demoInMemoryOAuthProvider.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -147,19 +147,12 @@ export const setupAuthServer = (authServerUrl: URL): OAuthMetadata => {
147147
authApp.use(express.urlencoded());
148148

149149
// Add OAuth routes to the auth server
150+
// NOTE: this will also add a protected resource metadata route,
151+
// but it won't be used, so leave it.
150152
authApp.use(mcpAuthRouter({
151153
provider,
152154
issuerUrl: authServerUrl,
153155
scopesSupported: ['mcp:tools'],
154-
// Resource metadata doesn't make sense on an Authorization server,
155-
// but, we're abusing the SDK to create a standalone Authorization server here.
156-
// In practice, developers should use an existing authorization server
157-
// at their organization, a 3rd party authorization server, or
158-
// have their MCP server be an authorization server via using `mcpAuthRouter`
159-
// directly in their server.
160-
protectedResourceOptions: {
161-
serverUrl: authServerUrl,
162-
},
163156
}));
164157

165158
authApp.post('/introspect', async (req: Request, res: Response) => {

src/server/auth/middleware/bearerAuth.test.ts

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,11 @@ import { Request, Response } from "express";
22
import { requireBearerAuth } from "./bearerAuth.js";
33
import { AuthInfo } from "../types.js";
44
import { InsufficientScopeError, InvalidTokenError, OAuthError, ServerError } from "../errors.js";
5-
import { OAuthServerProvider } from "../provider.js";
6-
import { OAuthRegisteredClientsStore } from "../clients.js";
5+
import { OAuthTokenVerifier } from "../provider.js";
76

8-
// Mock provider
7+
// Mock verifier
98
const mockVerifyAccessToken = jest.fn();
10-
const mockProvider: OAuthServerProvider = {
11-
clientsStore: {} as OAuthRegisteredClientsStore,
12-
authorize: jest.fn(),
13-
challengeForAuthorizationCode: jest.fn(),
14-
exchangeAuthorizationCode: jest.fn(),
15-
exchangeRefreshToken: jest.fn(),
9+
const mockVerifier: OAuthTokenVerifier = {
1610
verifyAccessToken: mockVerifyAccessToken,
1711
};
1812

@@ -50,7 +44,7 @@ describe("requireBearerAuth middleware", () => {
5044
authorization: "Bearer valid-token",
5145
};
5246

53-
const middleware = requireBearerAuth({ provider: mockProvider });
47+
const middleware = requireBearerAuth({ verifier: mockVerifier });
5448
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
5549

5650
expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token");
@@ -59,7 +53,7 @@ describe("requireBearerAuth middleware", () => {
5953
expect(mockResponse.status).not.toHaveBeenCalled();
6054
expect(mockResponse.json).not.toHaveBeenCalled();
6155
});
62-
56+
6357
it("should reject expired tokens", async () => {
6458
const expiredAuthInfo: AuthInfo = {
6559
token: "expired-token",
@@ -73,7 +67,7 @@ describe("requireBearerAuth middleware", () => {
7367
authorization: "Bearer expired-token",
7468
};
7569

76-
const middleware = requireBearerAuth({ provider: mockProvider });
70+
const middleware = requireBearerAuth({ verifier: mockVerifier });
7771
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
7872

7973
expect(mockVerifyAccessToken).toHaveBeenCalledWith("expired-token");
@@ -87,7 +81,7 @@ describe("requireBearerAuth middleware", () => {
8781
);
8882
expect(nextFunction).not.toHaveBeenCalled();
8983
});
90-
84+
9185
it("should accept non-expired tokens", async () => {
9286
const nonExpiredAuthInfo: AuthInfo = {
9387
token: "valid-token",
@@ -101,7 +95,7 @@ describe("requireBearerAuth middleware", () => {
10195
authorization: "Bearer valid-token",
10296
};
10397

104-
const middleware = requireBearerAuth({ provider: mockProvider });
98+
const middleware = requireBearerAuth({ verifier: mockVerifier });
10599
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
106100

107101
expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token");
@@ -124,7 +118,7 @@ describe("requireBearerAuth middleware", () => {
124118
};
125119

126120
const middleware = requireBearerAuth({
127-
provider: mockProvider,
121+
verifier: mockVerifier,
128122
requiredScopes: ["read", "write"]
129123
});
130124

@@ -155,7 +149,7 @@ describe("requireBearerAuth middleware", () => {
155149
};
156150

157151
const middleware = requireBearerAuth({
158-
provider: mockProvider,
152+
verifier: mockVerifier,
159153
requiredScopes: ["read", "write"]
160154
});
161155

@@ -169,7 +163,7 @@ describe("requireBearerAuth middleware", () => {
169163
});
170164

171165
it("should return 401 when no Authorization header is present", async () => {
172-
const middleware = requireBearerAuth({ provider: mockProvider });
166+
const middleware = requireBearerAuth({ verifier: mockVerifier });
173167
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
174168

175169
expect(mockVerifyAccessToken).not.toHaveBeenCalled();
@@ -189,7 +183,7 @@ describe("requireBearerAuth middleware", () => {
189183
authorization: "InvalidFormat",
190184
};
191185

192-
const middleware = requireBearerAuth({ provider: mockProvider });
186+
const middleware = requireBearerAuth({ verifier: mockVerifier });
193187
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
194188

195189
expect(mockVerifyAccessToken).not.toHaveBeenCalled();
@@ -214,7 +208,7 @@ describe("requireBearerAuth middleware", () => {
214208

215209
mockVerifyAccessToken.mockRejectedValue(new InvalidTokenError("Token expired"));
216210

217-
const middleware = requireBearerAuth({ provider: mockProvider });
211+
const middleware = requireBearerAuth({ verifier: mockVerifier });
218212
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
219213

220214
expect(mockVerifyAccessToken).toHaveBeenCalledWith("invalid-token");
@@ -236,7 +230,7 @@ describe("requireBearerAuth middleware", () => {
236230

237231
mockVerifyAccessToken.mockRejectedValue(new InsufficientScopeError("Required scopes: read, write"));
238232

239-
const middleware = requireBearerAuth({ provider: mockProvider });
233+
const middleware = requireBearerAuth({ verifier: mockVerifier });
240234
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
241235

242236
expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token");
@@ -258,7 +252,7 @@ describe("requireBearerAuth middleware", () => {
258252

259253
mockVerifyAccessToken.mockRejectedValue(new ServerError("Internal server issue"));
260254

261-
const middleware = requireBearerAuth({ provider: mockProvider });
255+
const middleware = requireBearerAuth({ verifier: mockVerifier });
262256
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
263257

264258
expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token");
@@ -276,7 +270,7 @@ describe("requireBearerAuth middleware", () => {
276270

277271
mockVerifyAccessToken.mockRejectedValue(new OAuthError("custom_error", "Some OAuth error"));
278272

279-
const middleware = requireBearerAuth({ provider: mockProvider });
273+
const middleware = requireBearerAuth({ verifier: mockVerifier });
280274
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
281275

282276
expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token");
@@ -294,7 +288,7 @@ describe("requireBearerAuth middleware", () => {
294288

295289
mockVerifyAccessToken.mockRejectedValue(new Error("Unexpected error"));
296290

297-
const middleware = requireBearerAuth({ provider: mockProvider });
291+
const middleware = requireBearerAuth({ verifier: mockVerifier });
298292
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
299293

300294
expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token");
@@ -311,7 +305,7 @@ describe("requireBearerAuth middleware", () => {
311305
it("should include resource_metadata in WWW-Authenticate header for 401 responses", async () => {
312306
mockRequest.headers = {};
313307

314-
const middleware = requireBearerAuth({ provider: mockProvider, resourceMetadataUrl });
308+
const middleware = requireBearerAuth({ verifier: mockVerifier, resourceMetadataUrl });
315309
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
316310

317311
expect(mockResponse.status).toHaveBeenCalledWith(401);
@@ -329,7 +323,7 @@ describe("requireBearerAuth middleware", () => {
329323

330324
mockVerifyAccessToken.mockRejectedValue(new InvalidTokenError("Token expired"));
331325

332-
const middleware = requireBearerAuth({ provider: mockProvider, resourceMetadataUrl });
326+
const middleware = requireBearerAuth({ verifier: mockVerifier, resourceMetadataUrl });
333327
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
334328

335329
expect(mockResponse.status).toHaveBeenCalledWith(401);
@@ -347,7 +341,7 @@ describe("requireBearerAuth middleware", () => {
347341

348342
mockVerifyAccessToken.mockRejectedValue(new InsufficientScopeError("Required scopes: admin"));
349343

350-
const middleware = requireBearerAuth({ provider: mockProvider, resourceMetadataUrl });
344+
const middleware = requireBearerAuth({ verifier: mockVerifier, resourceMetadataUrl });
351345
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
352346

353347
expect(mockResponse.status).toHaveBeenCalledWith(403);
@@ -371,7 +365,7 @@ describe("requireBearerAuth middleware", () => {
371365
authorization: "Bearer expired-token",
372366
};
373367

374-
const middleware = requireBearerAuth({ provider: mockProvider, resourceMetadataUrl });
368+
const middleware = requireBearerAuth({ verifier: mockVerifier, resourceMetadataUrl });
375369
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
376370

377371
expect(mockResponse.status).toHaveBeenCalledWith(401);
@@ -395,7 +389,7 @@ describe("requireBearerAuth middleware", () => {
395389
};
396390

397391
const middleware = requireBearerAuth({
398-
provider: mockProvider,
392+
verifier: mockVerifier,
399393
requiredScopes: ["read", "write"],
400394
resourceMetadataUrl
401395
});
@@ -417,12 +411,12 @@ describe("requireBearerAuth middleware", () => {
417411

418412
mockVerifyAccessToken.mockRejectedValue(new ServerError("Internal server issue"));
419413

420-
const middleware = requireBearerAuth({ provider: mockProvider, resourceMetadataUrl });
414+
const middleware = requireBearerAuth({ verifier: mockVerifier, resourceMetadataUrl });
421415
await middleware(mockRequest as Request, mockResponse as Response, nextFunction);
422416

423417
expect(mockResponse.status).toHaveBeenCalledWith(500);
424418
expect(mockResponse.set).not.toHaveBeenCalledWith("WWW-Authenticate", expect.anything());
425419
expect(nextFunction).not.toHaveBeenCalled();
426420
});
427421
});
428-
});
422+
});

0 commit comments

Comments
 (0)