fix: skip eager token refresh when OAuth metadata is unavailable (#3240)

Closed
ZS
2mo ago
+57-2

Problem

When the authorization server lives under a non-root path (e.g. https://host/oauth2/api/v1/token), the eager token refresh at the top of async_auth_flow hits the wrong endpoint.

Root cause: _refresh_token falls back to urljoin(get_authorization_base_url(server_url), "/token") when oauth_metadata is None. get_authorization_base_url strips the path, so a server at /oauth2/api/v1/token gets https://host/token instead.

This happens because the eager refresh runs before any PRM/ASM metadata discovery — so oauth_metadata is always None on a restart with cached-but-expired tokens.

Fix

Add and self.context.oauth_metadata is not None to the eager refresh guard. When metadata is missing:

  1. Skip the eager refresh (we don't know the real token endpoint)
  2. Let the request proceed with the stale token
  3. Receive 401 → run full PRM/ASM discovery → learn the correct token_endpoint
  4. Refresh or re-authorize with the right endpoint

This is correct because:

  • With metadata: eager refresh works as before (we know the endpoint)
  • Without metadata + token valid: no refresh needed, request succeeds
  • Without metadata + token expired: skip → 401 → discovery → correct endpoint

Fixes #3240