Only use path-based discovery URLs from the authorization server to discover metadata (#1070)
This commit is contained in:
parent
783d53be10
commit
664e66e575
2 changed files with 11 additions and 21 deletions
|
|
@ -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)
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
Loading…
Reference in a new issue