Skip to content

W-17440369: Use instanceUrl host when refreshing OAuth tokens#2936

Open
wmathurin wants to merge 2 commits into
forcedotcom:devfrom
wmathurin:W-17440369-instance-url-token-refresh
Open

W-17440369: Use instanceUrl host when refreshing OAuth tokens#2936
wmathurin wants to merge 2 commits into
forcedotcom:devfrom
wmathurin:W-17440369-instance-url-token-refresh

Conversation

@wmathurin

Copy link
Copy Markdown
Contributor

Summary

Token refresh previously always POSTed to loginServer (e.g. login.salesforce.com). This breaks DPoP htu binding (RFC 9449 §4.3) when the login-pool redirects to the user's My Domain, and adds an unnecessary round-trip on every refresh for Bearer flows.

Mirrors the iOS fix from PR #4074.

Changes

OAuth2.java

  • Adds overrideLoginServerIfNeeded(loginServer, instanceServer, communityId, communityUrl) static helper with precedence: communityUrl > instanceServer > loginServer. instanceServer is null until after the first token response, so the code-exchange path falls through to loginServer naturally with no special-casing.
  • Updates getOpenIDToken() to accept and apply the same precedence (new parameters: instanceServer, communityId, communityUrl).

ClientManager.javaAccMgrAuthTokenProvider.refreshStaleToken()

  • Uses overrideLoginServerIfNeeded before calling refreshAuthToken
  • Adds target-host log line (host only, no token values)

AuthenticatorService.javaAuthenticator.getAuthToken()

  • Same update as ClientManager

OAuth2OverrideLoginServerTests.kt — 6 new unit tests:

  1. Instance server populated → returns instance server
  2. Instance server null → returns login server
  3. Community ID + URL set → returns community URL (even when instance server is also set)
  4. Community ID set but URL null → falls back to instance server
  5. All null (code exchange path) → returns login server
  6. Malformed community URL → falls back to instance server

OAuth2Test.java — Updated testGetOpenIDToken call to match new getOpenIDToken signature.

Test plan

  • 6 new OAuth2OverrideLoginServerTests pass on emulator (API 36)
  • Existing OAuth2MockTests (6 tests) pass
  • LoginServerManagerTest and ScopeParserTest pass
  • Compiles clean (only pre-existing deprecation warnings, none from this PR)

Adds OAuth2.overrideLoginServerIfNeeded() with precedence:
  communityUrl > instanceServer > loginServer

instanceServer is null until after the first token response, so the
code-exchange path naturally falls through to loginServer with no
special casing.

Updates both token-refresh call sites (ClientManager,
AuthenticatorService) to use the helper, and updates getOpenIDToken()
to accept and apply the same precedence. Adds a target-host log line
at each refresh call site.

Mirrors the iOS fix from PR #4074 (SFOAuthCredentials.overrideDomainIfNeeded).

Tests: 6 new unit tests in OAuth2OverrideLoginServerTests covering
precedence, fallback, community precedence, code-exchange neutrality,
and malformed-URL fallback.
@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown
1 Warning
⚠️ libs/SalesforceSDK/src/com/salesforce/androidsdk/auth/AuthenticatorService.java#L58 - Do not place Android context classes in static fields (static reference to Authenticator which has field context pointing to Context); this is a memory leak

Generated by 🚫 Danger

MockK's relaxed mocks return "" (not null) for unstubbed Java String
getters. Guard against empty strings in the same way as null to prevent
new URI("") from constructing a relative URI that breaks OkHttp.

Also adds a 7th test covering the empty-instanceServer case.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant