Skip to content

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

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

    P2Moderate issues affecting some users, edge cases, potentially valuable featureauthIssues and PRs related to Authentication / OAuthbugSomething isn't workingready for workEnough information for someone to start working on

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions