How to setup OAuth JWT in the Salesforce Connector

In this post, we'll explain all the steps required to connect a Mule application to Salesforce using the Salesforce connector using the OAuth JWT flow.

You can also create your own certificate for the OAuth JWT flow with Salesforce or with OpenSSL (signed by a CA or self-signed). Both options are very well explained in this video from my dear Stefano Bernardini, Mulesoft Ambassador.



In this post, we’ll be using a self-signed certificate created by Salesforce but, keep in mind, that for Production environments a certificate issued by a Trusted Certificate Authority is always recommended.


1. Create the Certificate

  • Start from our Salesforce org
  • Go Setup > Certificate and Key Management
  • Click on Create Self-Signed Certificate
  • Provide a name for our certificate - in our case, we’ll name it mule_jwt_cert
  • After you click on save, the certificate will be created and you’ll get in the next window the details of your certificate. 
  • Click on Download Certificate and save it to a separate folder, we’ll use it later.
  • We’ll get back to the Certificate and Management page. We should now see our certificate in the list of certificates. 
  • From there we’ll export our certificate to a keystore. Click on Export to Keystore.
  • Provide a password for your keystore and write it down. We’ll use it later to set up the JWT auth in the Mule app.
  • You’ll get a .jks file. Save it to our separate folder.
  • This jks should have:
    • The certificate
    • The Private Key
    • The Public Key
  • We can verify that with Key Store Explorer for example


2. Create the connected app in Salesforce

  • Start in your Salesforce org.
  • To create the Connected App we’ll go to Setup > App Manager (use finder)
  • Click on New Connected App on the top right corner
  • In the configuration of our New Connected App
    • Provide a name for the App. In this example, we’ll name it mule_jwt_sf_connected_app
    • Provide an email and phone for Contact Email and Contact Phone. The values for Contact Email or Phone are only for auditing purposes, this information is not used in any further configuration.
    • Select the Enable OAuth Settings
    • Provide a Callback URL. In this case, it can be anything as we’ll not use it for this OAuth flow. For this example we’ll just use http://localhost:8081/callback
    • Select the Use digital signatures and upload the certificate we downloaded before.
    • In the Selected OAuth Scopes we’ll select the following ones:
      • Manage user data via APIs (api)
      • Perform requests at any time (refresh_token, offline_access)
    • The rest of the values we can leave them as default. Click Save at the bottom of the page
    • App Manager will inform you it can take up to 10 minutes to get your connected app ready. Click on continue
    • In the next window, within the details of our connected app, we’ll go to the API (Enable OAuth Settings) section and click on Manage Consumer Details
    • We’ll be prompted to Verify Your Identity. We’ll need to provide a verification code that has been sent to our email. Enter the code and we should see the Consumer key and Consumer Secret of our connected app.
    • Copy the Consumer Key, we’ll use it later in the Mule app. 
  • Go back to Setup > App Manager and from the list of apps, find our Connected App and click on Manage in the right dropdown
  • From here click on Edit Policies
  • In Permitted Users select Admin approved users are pre-authorized and click Save
  • Back to the Manage Connected app page, scroll down to the Profiles section and click Manage Profiles
  • In the list of Profiles, select the Profile that should have access to this connected app. For the purpose of this example, we’re using a System Admin profile. You should use a profile with the minimum permissions required for your use case. Depending on your use case you might need only a technical user or you might need to impersonate a real user, allowing all the users associated with this Profile to propagate their identity down to the mule app.
  • Check out these couple of posts to understand better what user you should use for your Mule app:


3. Create the Mule App

  • From Studio, create a New Mule Project
  • In the Mule Palette, add the Salesforce Module connector

Design the Flow

  • Drag and drop the following elements (see screenshot for details of the flow)
    • A Listener
    • 2 Loggers - before and after the SF Query
    • A SF Query, from the Salesforce Connector
    • A Transform Message - to convert the outcome of the flow to JSON


Upload the Key store

Right-click on the project name and select Show In > System Explorer. That should open a explorer window at the main folder of our project. 

  • From there, go to resources and upload the jks file of our keystore.
  • Back to Studio, if you right-click again in the name of our project and click Refresh we should see our keystore under the src/main/resources folder.


HTTP Listener

  • Our Mule app will be listening on port 8081
  • Our endpoint will be /accounts


Loggers

As a best practice, we’ll add a logger before and after the Salesforce connector query


Salesforce Connector Query

  • Go to the Global Elements tab and create a new Salesforce Config for the connector
  • Provide a descriptive name for the Configuration
  • In the Connection dropdown select OAuth JWT
  • Provide the following details in the General Tab:
    • In Consumer Key - Paste the Consumer key of our Salesforce Connected App
    • In Key store - enter the name of the jks file. If you’re using a different path for your key store you can use the three points button and navigate to that location.
    • In Store Password - provide the password of our keystore
    • In principal - the email of the user we used to create the Connected App
  • The last two parameters, Token Endpoint and Audience url are interconnected in this way:
    • For the Audience URL, you can leave it blank only if you don’t use your custom domain for the token endpoint. If you do so, you need to provide a value for this field, which can be login.salesforce.com or test.salesforce.com depending on the type of account you’re using
    • Explanation: The Connector will build a JWT token with the information you provided. In the claims set section of the token, there will be a claim named aud which specifies the audience. The value of this claim has to be login.salesforce.com or test.salesforce.com. The connector, when building the claims, will take the value of the Audience url parameter as aud. If it does not find any value it will take the hostname of the token endpoint. That's why leaving the field blank and using a custom domain won't work. More info here

  • Click on Test Connection
    • If you see the following error, get back to our Salesforce Connected App and review
      • the Profiles allowed to use the app
      • If you’ve selected the option of Admin approved users are pre-authorized

  • Once we’ve got the configuration of the connector and how it will get authenticated with JWT, let’s set up the Query
  • Click on the Query Element and enter the following configuration in the Properties tab
    • Enter a descriptive name in Display Name - in our example Get Accounts
    • In the Connector Configuration pick up the Salesforce Config global element we’ve just defined in the previous step
    • In the Salesforce Query enter the SOQL query to get the info we want to get from Salesforce. In our case it’s just a query to get Accounts


Transformation

  • The output from Salesforce will be in Java format. We’ll add a transformation element to translate that to JSON format, so that our API provides responses in JSON
  • In the transform element, just add the following in the Output:
%dw 2.0
output application/json
---
payload

This will just convert the records coming from Salesforce in Java format to JSON


Test the App

  • From Studio, right click on the designer canvas and click Run project, that will deploy our app locally
  • From our testing tool, here we use Postman we’ll send a GET to http://localhost:8081/accounts
  • If everything went well we should get the list of Accounts records
In the next post we'll be adding mTLS to this configuration. Click here to continue!
Previous Post Next Post