diff --git a/src/client/auth.test.ts b/src/client/auth.test.ts index 6c924898a..5ba3975b6 100644 --- a/src/client/auth.test.ts +++ b/src/client/auth.test.ts @@ -712,16 +712,12 @@ describe('OAuth Authorization', () => { it('generates correct URLs for server with path', () => { const urls = buildDiscoveryUrls('https://auth.example.com/tenant1'); - expect(urls).toHaveLength(4); + expect(urls).toHaveLength(3); expect(urls.map(u => ({ url: u.url.toString(), type: u.type }))).toEqual([ { url: 'https://auth.example.com/.well-known/oauth-authorization-server/tenant1', type: 'oauth' }, - { - url: 'https://auth.example.com/.well-known/oauth-authorization-server', - type: 'oauth' - }, { url: 'https://auth.example.com/.well-known/openid-configuration/tenant1', type: 'oidc' @@ -736,7 +732,7 @@ describe('OAuth Authorization', () => { it('handles URL object input', () => { const urls = buildDiscoveryUrls(new URL('https://auth.example.com/tenant1')); - expect(urls).toHaveLength(4); + expect(urls).toHaveLength(3); expect(urls[0].url.toString()).toBe('https://auth.example.com/.well-known/oauth-authorization-server/tenant1'); }); }); @@ -763,28 +759,28 @@ describe('OAuth Authorization', () => { }; it('tries URLs in order and returns first successful metadata', async () => { - // First OAuth URL fails with 404 + // First OAuth URL (path before well-known) fails with 404 mockFetch.mockResolvedValueOnce({ ok: false, status: 404 }); - // Second OAuth URL (root) succeeds + // Second OIDC URL (path before well-known) succeeds mockFetch.mockResolvedValueOnce({ ok: true, status: 200, - json: async () => validOAuthMetadata + json: async () => validOpenIdMetadata }); const metadata = await discoverAuthorizationServerMetadata('https://auth.example.com/tenant1'); - expect(metadata).toEqual(validOAuthMetadata); + expect(metadata).toEqual(validOpenIdMetadata); // Verify it tried the URLs in the correct order const calls = mockFetch.mock.calls; expect(calls.length).toBe(2); expect(calls[0][0].toString()).toBe('https://auth.example.com/.well-known/oauth-authorization-server/tenant1'); - expect(calls[1][0].toString()).toBe('https://auth.example.com/.well-known/oauth-authorization-server'); + expect(calls[1][0].toString()).toBe('https://auth.example.com/.well-known/openid-configuration/tenant1'); }); it('continues on 4xx errors', async () => { @@ -878,7 +874,7 @@ describe('OAuth Authorization', () => { expect(metadata).toBeUndefined(); // Verify that all discovery URLs were attempted - expect(mockFetch).toHaveBeenCalledTimes(8); // 4 URLs × 2 attempts each (with and without headers) + expect(mockFetch).toHaveBeenCalledTimes(6); // 3 URLs × 2 attempts each (with and without headers) }); }); diff --git a/src/client/auth.ts b/src/client/auth.ts index 5e48345a3..ea2400a25 100644 --- a/src/client/auth.ts +++ b/src/client/auth.ts @@ -669,8 +669,7 @@ export async function discoverOAuthMetadata( * Builds a list of discovery URLs to try for authorization server metadata. * URLs are returned in priority order: * 1. OAuth metadata at the given URL - * 2. OAuth metadata at root (if URL has path) - * 3. OIDC metadata endpoints + * 2. OIDC metadata endpoints at the given URL */ export function buildDiscoveryUrls(authorizationServerUrl: string | URL): { url: URL; type: 'oauth' | 'oidc' }[] { const url = typeof authorizationServerUrl === 'string' ? new URL(authorizationServerUrl) : authorizationServerUrl; @@ -706,18 +705,13 @@ export function buildDiscoveryUrls(authorizationServerUrl: string | URL): { url: type: 'oauth' }); - // Root path: https://example.com/.well-known/oauth-authorization-server - urlsToTry.push({ - url: new URL('/.well-known/oauth-authorization-server', url.origin), - type: 'oauth' - }); - - // 3. OIDC metadata endpoints + // 2. OIDC metadata endpoints // RFC 8414 style: Insert /.well-known/openid-configuration before the path urlsToTry.push({ url: new URL(`/.well-known/openid-configuration${pathname}`, url.origin), type: 'oidc' }); + // OIDC Discovery 1.0 style: Append /.well-known/openid-configuration after the path urlsToTry.push({ url: new URL(`${pathname}/.well-known/openid-configuration`, url.origin),