Salesforce Connected Apps and OAuth Tokens
In this post, we will explore in detail how to generate OAuth Access tokens with Salesforce Connected apps.
What is a Salesforce Connected App?
A Salesforce Connected App is an integration framework to enable external systems to integrate with any Salesforce systems. For example, imagine a Salesforce customer wants to have a nightly ETL job to pull out cases that were created during the day in their Salesforce org. Salesforce exposes APIs to export cases from an org, but how would this ETL job prove its identity to the corresponding Salesforce API. The Salesforce Connected App is the answer. You can read more about connected apps here.
A word on OAuth.
OAuth can be simply described like this: A friend’s friend is my friend and the OG friend tells me how much to trust the new friend. The “how much to trust” part is conveyed via something called an OAuth token. In a typical OAuth system, there are multiple ways to get such a token from an identity provider. These “ways” are generally referred to as “OAuth flows”. You can read about the various OAuth flows supported by Salesforce here.
In the context of establishing the identity of external systems, Salesforce Connected apps broker OAuth access tokens with certain privileges or scopes to the external service. The external service then includes this access token as an ID card when it talks to a Salesforce API. Simply put, a connected app tells a Salesforce API who the external service is and how much should Salesforce trust it. The “trust level” is expressed via the OAuth scopes (the privileges) that are configured by the Salesforce org admin (the customer) when creating the connected app.
In this post will discuss how to get the OAuth token from a Salesforce Connected App using the JWT Bearer Flow because this is one of the most commonly used flows when creating a server-to-server integration over OAuth.
Time to play the game!
Before we get started log into your Salesforce org. If you don’t have one, you can get one easily.
Now, follow these steps on the Salesforce Org:
- Navigate to the “Setup” page of your org, it should look something like the following:
- Search for “App Manager”. App Manager as the name suggests is a place to manage all apps in your Salesforce Org.
- Click the “Create New Connected App”
- Fill out the App Name and contact email (this should be the username you used to log into the Salesforce org and make sure this user has admin access to the Org)
- Check the “Enable OAuth Settings” checkbox
- Add a callback URL. When generating an OAuth token for certain flows like the User-Agent Flow, Salesforce redirects the user to a URL after a successful login. This redirect URL is the callback and is usually a client application that had directed the user to Salesforce in the first place for login and OAuth authorization purposes. For the JWT Bearer flow, this value can be any valid URL, as this flow does not include redirection.
- Generate yourself a nice public/private encryption keys. Just copy-paste the following commands on a terminal window and you will have two files named “server.crt” (public certificate) and “server.key” (private key) in the current folder. You will need the “server.crt” in the next step and “server.key” later. Make sure you have openssl installed on your machine.
openssl genrsa -des3 -passout pass:password -out server.pass.key 2048;openssl rsa -passin pass:password -in server.pass.key -out server.key;openssl req -new -key server.key -out server.csr;openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt;
- Check the “Use Digital Signatures” checkbox, and upload your “server.crt” file
- From the “Selected OAuth Scopes” list, select and add the following OAuth scopes:
- “Perform requests at anytime (refresh_token, offline_access)”. This scope is used to allow the generation of the OAuth token
- Add any other scope that you would like the token bearer to have, for example, if the bearer needs to talk to the Einstein Bots API, then add the “chatbot_api” scope
- You can read more about Salesforce OAuth Scopes here - Leave all other fields as is, and click save. You should see your Connected App. Click “Manage” and then click “Edit Policies”
- Under “OAuth Policies” for the “Permitted User” pick-list, select the “Admin approved users are pre-authorized” policy. We need to do this because of the JWT bearer flow, we need to add certain user profiles to the connected app, and users of only these profiles can request an OAuth token from this connected app
- Click “Save” and scroll down to “Profiles” and click “Manage Profiles”. We will add all expected profiles here. For the purposes of this demonstration add the “Standard User” and “System Administrator” profiles
- Go back to “App Manager” again and you should see your shiny new Connected App in the list
- On the extreme right, click the little drop-down button shown along the row of your Connected App and click “View”
- You should see your App’s “Consumer Key”, copy this value. In the ≥ 238 releases, instead of the copy button, you will see a “View” button under the “Consumer Key” field, this will redirect you to a different page in your org where you will be able to see/copy the consumer key. This is a new security feature.
Congratulations, you have just setup a Salesforce Connected App with OAuth enabled.
Now, let’s generate a JWT (JSON Web Token) which later we will exchange with Salesforce’s auth servers for an OAuth token. You can use any relevant tool to generate this JWT, but for the purposes of this demonstration, we will use https://jwt.io/ and follow these steps:
- In the “Header” section add the following (the JWT encoding scheme):
{
"alg":"RS256"
}
- In the “Verify Signature” section, paste your public certificate and private key (on Linux/Mac, you can
cat
on them on the command-line and copy the output; on Windows, you can open these files with any text editor) - in the “Payload” section, add the following (make sure you add your corresponding details):
{
"iss": <your connected app's consumer-key>,
"sub": <the contact email you used when creating the connected app>
"aud": "https://login.salesforce.com/"
"exp": <desired expiry in the epoch seconds format>
}
- You should see a JWT generated on the left panel, copy that JWT. We will now exchange it for an OAuth token
- use the following cURL command to exchange the above JWT for an OAuth access token:
curl --location --request POST 'https://login.salesforce.com/services/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'assertion=<YOUR JWT FROM ABOVE>' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer'
- You should see a response of the following form:
{
"access_token": "<OAuth Access Token>",
"scope": "<a cvs of scopes you chose when creating your connected app>",
"instance_url": "<your Salesforce org's domain URL>",
"id": "https://login.salesforce.com/id/<your org-id>/<user-id>",
"token_type": "Bearer"
}
That’s it, you have an OAuth Access token to use as a “Bearer” token when talking to any official Salesforce API.