Pavan
4 min readJan 19, 2023

--

Client credentials flow with Named credentials in Salesforce

The approach discussed in this writeup is by Chuck liddell, covered in the Pluralsight course. (https://www.pluralsight.com/courses/play-by-play-authenticating-external-app-service-integrations-salesforce)

The code is available at: https://github.com/cpavnn/sf-client-credentials-flow/blob/main/src/classes/ClientCredentialsAuth.cls

Named credentials simplifies and manages all authentication for callouts.

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_named_credentials.htm

For OAuth flows, currently Named credentials just supports the Authorization grant flow ( https://auth0.com/docs/flows/authorization-code-flow )

Image credit: https://auth0.com/docs/flows/authorization-code-flow

For Machine to Machine interactions, Client credentials flow is preferred

Image credit: https://auth0.com/docs/flows/client-credentials-flow

If we try to manage authentication in a custom way, the token storage and management will be a challenge, and in Salesforce there are NO good options of storing secrets securely. (We can store them in Managed package, However that’s a separate topic of discussion)

Salesforce provides AuthProviderPluginClass to create a custom OAuth-based authentication provider plug-in for single sign-on in to Salesforce (https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_class_Auth_AuthProviderPluginClass.htm)

If we look the observe the above two mentioned flows from the step 6 of Authorisation grant flow, the further number of steps remain more or less same.
The idea is we use the AuthProviderPluginClass to support the client credentials flow and handle the 1 to 5, and orchestrate from step 6, so that Named credentials supports the flow

Lets look at the code: https://github.com/cpavnn/sf-client-credentials-flow/blob/main/src/classes/ClientCredentialsAuth.cls

Deploy the Apex class to your org

Create Custom metadata type to hold the config details such as Token endpoint, client id etc

Create a Auth. Provider, and choose the Apex class name in Provider type Dropdown

The place holders for Client Id, Client Secret, Token Endpoint, Callback URL are defined in the Custom metadata in Step 2
The Callback URL in the Salesforce configuration section will be generated once you save the Auth. Provider, Copy the Callback URL and Put the same in Callback URL in Auth. Provider Details

The first method, the plugin picks up the custom metadata type config and pass the same to Map<string, string> authProviderConfiguration

The second method initiate, Returns the URL where the user is redirected for authentication.
Here we directly call the callback URL of salesforce instead of opening the authentication page, skipping the other steps
Named credentials thinks, we have covered Steps 1 to 5

More details on the stateToPropogate https://salesforce.stackexchange.com/questions/224231/salesforce-no-oauth-state-state-not-valid

The third method handleCallback, Uses the authentication provider’s supported authentication protocol to return an OAuth access token, OAuth secret or refresh token, and the state passed in when the request for the current user was initiated.
Here we build a custom http request with the desired params, method and body, and parse the response and return AuthProviderTokenResponse
By this we will have a desired token to access the resource API

The fourth method refresh, Usually the Auth provider wont return a refresh token for Client credentials flow, and will have expiry time for the token
We can have custom implementation to refresh the token by again hitting the token endpoint and the access token
There are few caveats around this, make sure to read the documentation and few supporting links
https://salesforce.stackexchange.com/questions/248596/refresh-token-using-salesforce-named-credentials-and-auth-provider

https://developer.salesforce.com/forums/?id=9062I000000g8fzQAA

The last method getUserInfo, we will return a fake user as the Client credentials flow is not tied one particular user

Create Named credentials

Fill in the details
Identity type: Named Principal
Authentication Protocol: OAuth 2.0
Authentication Provider: Choose the created Auth. Provider in Step 3
Start Authentication Flow on Save: Check

Once clicked on Save, the plugin code will execute and get token and store it securely

--

--