Skip to content

startAuthorization silently redirects to wrong URL when AS metadata discovery fails for non-root paths #1716

@RyanDJLee

Description

@RyanDJLee

Bug: startAuthorization silently redirects to wrong URL when AS metadata discovery fails

Package: packages/client/src/client/auth.ts

Problem

When discoverAuthorizationServerMetadata() returns undefined (all discovery URLs returned 4xx or were unreachable), startAuthorization() falls back to constructing the authorization URL as:

authorizationUrl = new URL('/authorize', authorizationServerUrl);

new URL('/authorize', authorizationServerUrl) uses an absolute path, which replaces the entire pathname of authorizationServerUrl. When the authorization server has a subpath (e.g. https://example.com/admin), the result is https://example.com/authorize — the /admin prefix is silently lost.

The same pattern exists for the token endpoint fallback in executeTokenRequest():

const tokenUrl = metadata?.token_endpoint ? new URL(metadata.token_endpoint) : new URL('/token', authorizationServerUrl);

And the registration endpoint fallback in registerClient():

registrationUrl = new URL('/register', authorizationServerUrl);

Reproduction

  1. PRM (/.well-known/oauth-protected-resource) returns authorization_servers: ["https://example.com/admin"]
  2. AS metadata discovery at https://example.com/.well-known/oauth-authorization-server/admin returns 404
  3. SDK constructs new URL('/authorize', 'https://example.com/admin')https://example.com/authorize
  4. User is redirected to a nonexistent authorization endpoint
  5. The actual correct endpoint (https://example.com/admin/oauth/authorize) is never reached

Impact

  • Silent failure: no error is thrown; the user sees a broken redirect with no diagnostic info
  • Path loss: any authorization server with a non-root path is affected
  • Masks real errors: the actual cause (AS metadata unreachable) is hidden behind a mysterious redirect failure

Proposed fix

When metadata is undefined and the authorization server URL has a non-root path, throw an error instead of guessing. The fallback to /authorize, /token, and /register should only apply when the AS is at the domain root (where it's a reasonable guess per RFC 6749 defaults).

Affected locations:

  • startAuthorization()/authorize fallback (line ~1204)
  • executeTokenRequest()/token fallback (line ~1286)
  • registerClient()/register fallback (line ~1533)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions