Skip to content

Add OAuth refresh token reuse and rotation support - #1668

Open
markmainline wants to merge 2 commits into
forcedotcom:masterfrom
markmainline:oauth-refresh-token-support
Open

markmainline wants to merge 2 commits into
forcedotcom:masterfrom
markmainline:oauth-refresh-token-support

Conversation

@markmainline

Copy link
Copy Markdown

Summary

This change enables unattended OAuth authentication when using
Salesforce External Client Apps (ECA) and PKCE.

The implementation:

  • Reuses stored refresh tokens on startup.
  • Obtains new access tokens using the refresh token grant.
  • Persists rotated refresh tokens returned by Salesforce.
  • Falls back to browser-based PKCE authentication when refresh token authentication fails.
  • Continues using existing encrypted refresh token storage in config.properties.

Files Changed

  • OAuthFlowHandler.java
  • LoginClient.java
  • OAuthServerFlow.java
  • AppConfig.java

Testing

Completed testing in:

  • UI mode
  • CLI mode
  • External Client App authentication
  • PKCE authentication
  • Refresh Token Rotation enabled
  • Multiple application restarts
  • Multiple machines (development workstation and Styx server)
  • Works after multiple days of unattended access.

Results

  • Initial login requires browser authentication.
  • Refresh tokens are encrypted and persisted.
  • Subsequent executions authenticate successfully using refresh tokens.
  • Rotated refresh tokens are persisted correctly.
  • Batch jobs execute successfully without browser interaction.

Motivation

This allows Data Loader to operate unattended using modern Salesforce OAuth authentication and provides a migration path away from SOAP login() based authentication.

@salesforce-cla

Copy link
Copy Markdown

Thanks for the contribution! Before we can merge this, we need @markmainline to sign the Salesforce Inc. Contributor License Agreement.

@markmainline

Copy link
Copy Markdown
Author

Additional testing information:

  • Development and testing performed between Thursday and Monday, then on to subsequent weeks successfully.
  • Tested using Salesforce External Client Apps (ECA) with PKCE authentication.
  • Refresh Token Rotation enabled throughout testing.
  • Tested across multiple application restarts.
  • Tested on multiple systems (development workstation and a separate server environment).
  • Successfully validated both UI mode and CLI/batch mode execution.
  • Verified unattended CLI execution with no browser interaction after the initial consent flow.
  • Verified refresh token persistence, refresh token rotation handling, and successful reuse of rotated tokens across multiple runs.
  • Tested after moving the modified JAR and encrypted configuration to a second machine and confirmed successful authentication and processing.

The primary goal of the testing was to validate unattended operation as a migration path away from SOAP login() authentication. In all test cases after the initial OAuth consent flow, authentication was performed using the stored refresh token without requiring further user interaction.

@markmainline

Copy link
Copy Markdown
Author

Worth also mentioning, that you will also need to create an entry in Salesforce for an External Client App. Setup -> App -> External Client App. Upload a consumer key/secret, setup the callback URL to: http://localhost:7171/OauthRedirect

Salesforce Configuration Prerequisites

Testing was performed using a Salesforce External Client App (ECA).

The following Salesforce configuration was required:

  • External Client App created in Salesforce.
  • OAuth enabled.
  • Consumer Key (Client ID) configured in Data Loader.
  • Consumer Secret configured in Data Loader.
  • PKCE authentication enabled.
  • OAuth scopes included:
    • api
    • refresh_token
  • Refresh Token Rotation enabled.

The first authentication requires an interactive browser-based OAuth consent flow.

During this initial authentication Salesforce issues:

  • Access Token
  • Refresh Token

The refresh token is then encrypted and stored in the Data Loader configuration. Subsequent executions authenticate using the stored refresh token and no longer require browser interaction.

The implementation was validated using both UI and CLI execution modes and supports refresh token rotation by persisting newly issued refresh tokens returned by Salesforce.

This pull request does not remove the existing OAuth/PKCE flow.

The browser-based PKCE flow remains the mechanism for obtaining the initial refresh token and acts as a fallback path if refresh token authentication fails.

@markmainline

Copy link
Copy Markdown
Author

Thanks for the contribution! Before we can merge this, we need @markmainline to sign the Salesforce Inc. Contributor License Agreement.

CLA has now been signed. The GitHub account associated with this pull request is markmainline and the verified email address is mark.tilley@mainline.uk.com. Please let me know if anything further is required.

@markmainline

Copy link
Copy Markdown
Author

The Salesforce CLA has been signed. A subsequent pull request (#1669) opened after signing has automatically received the cla:signed label. It looks as though this PR may simply need the CLA check re-run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant