Skip to content

Commit 846f67d

Browse files
committed
fix: preserve auth server path in OAuth metadata URL construction
Previously, the path was stripped when constructing the well-known OAuth metadata URL. Per RFC 8414 §3.1, the path must be preserved after the .well-known segment to support multitenant auth servers that encode tenant IDs in the path. - Fix oauthAuthServerMetadataUrl to preserve path segments - Add comprehensive test coverage for the function
1 parent 9051727 commit 846f67d

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

client/src/components/OAuthFlowProgress.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Button } from "./ui/button";
44
import { DebugInspectorOAuthClientProvider } from "@/lib/auth";
55
import { useEffect, useMemo, useState } from "react";
66
import { OAuthClientInformation } from "@modelcontextprotocol/sdk/shared/auth.js";
7+
import { oauthAuthServerMetadataUrl } from "@/utils/oauthUtils.ts";
78

89
interface OAuthStepProps {
910
label: string;
@@ -196,10 +197,7 @@ export const OAuthFlowProgress = ({
196197
<p className="text-xs text-muted-foreground">
197198
From{" "}
198199
{
199-
new URL(
200-
"/.well-known/oauth-authorization-server",
201-
authState.authServerUrl,
202-
).href
200+
oauthAuthServerMetadataUrl(authState.authServerUrl).href
203201
}
204202
</p>
205203
)}

client/src/utils/__tests__/oauthUtils.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
generateOAuthErrorDescription,
33
parseOAuthCallbackParams,
4+
oauthAuthServerMetadataUrl,
45
} from "@/utils/oauthUtils.ts";
56

67
describe("parseOAuthCallbackParams", () => {
@@ -76,3 +77,37 @@ describe("generateOAuthErrorDescription", () => {
7677
);
7778
});
7879
});
80+
81+
describe("oauthAuthServerMetadataUrl", () => {
82+
it("Returns metadata URL for simple auth server URL", () => {
83+
const input = new URL("https://auth.example.com");
84+
const result = oauthAuthServerMetadataUrl(input);
85+
expect(result.href).toBe(
86+
"https://auth.example.com/.well-known/oauth-authorization-server",
87+
);
88+
});
89+
90+
it("Returns metadata URL for auth server with path", () => {
91+
const input = new URL("https://auth.example.com/oauth/tenant/xyz");
92+
const result = oauthAuthServerMetadataUrl(input);
93+
expect(result.href).toBe(
94+
"https://auth.example.com/.well-known/oauth-authorization-server/oauth/tenant/xyz",
95+
);
96+
});
97+
98+
it("Strips trailing slash from path as per spec", () => {
99+
const input = new URL("https://auth.example.com/oauth/");
100+
const result = oauthAuthServerMetadataUrl(input);
101+
expect(result.href).toBe(
102+
"https://auth.example.com/.well-known/oauth-authorization-server/oauth",
103+
);
104+
});
105+
106+
it("Handles auth server URL with port", () => {
107+
const input = new URL("https://auth.example.com:8080");
108+
const result = oauthAuthServerMetadataUrl(input);
109+
expect(result.href).toBe(
110+
"https://auth.example.com:8080/.well-known/oauth-authorization-server",
111+
);
112+
});
113+
});

client/src/utils/oauthUtils.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,19 @@ export const generateOAuthErrorDescription = (
6363
.filter(Boolean)
6464
.join("\n");
6565
};
66+
67+
/**
68+
* Build the well-known OAuth 2.0 metadata URL from an authServerUrl.
69+
* Handles auth server paths per RFC 8414 §3.1.
70+
*
71+
* @param {URL} authServerUrl e.g. new URL("https://my.auth-server.com/oauth/tenant/xyz")
72+
* @returns {URL} e.g. new URL("https://my.auth-server.com/.well-known/oauth-authorization-server/oauth/tenant/xyz")
73+
*/
74+
export const oauthAuthServerMetadataUrl = (authServerUrl: URL): URL => {
75+
// Strip a trailing slash from the path (required by the spec)
76+
const path = authServerUrl.pathname.replace(/\/$/, "");
77+
78+
return new URL(
79+
`${authServerUrl.origin}/.well-known/oauth-authorization-server${path}`,
80+
);
81+
};

0 commit comments

Comments
 (0)