DEV Community

loading...
Cover image for OAuth 2.0 JWT Bearer Flow for Server-to-Server Integration

OAuth 2.0 JWT Bearer Flow for Server-to-Server Integration

kashyap_kalakbandi profile image kashyapkbandi ・4 min read

Isn't Salesforce a CRM ? Why are talking about JWT with Salesforce ?

Exactly, Salesforce is a CRM and also a solid developer friendly and completely flexible platform which supports integration with almost any of 3rd party systems , database, applications.

Hmmmm ok .. Why JWT ? There are other authorization flows which can be used.

For other types of mainstream authorization flows such as Webserver flow, you need a user presence to authenticate.

Sometimes you want to authorize servers to access data without interactively logging in each time the servers exchange information.

For these cases, you can use the OAuth 2.0 JSON Web Token (JWT) bearer flow.

But How ?

Well, This flow uses a certificate to sign the JWT request and doesn’t require explicit user interaction.
However, this flow does require prior approval of the client app.

How does this work in a nutshell ?

The client(who ever is trying to access salesforce data) posts a JWT to the Salesforce OAuth token endpoint.
Salesforce then processes the JWT, which includes a digital signature, and issues the access token(As per prior approval of app).

OK! Lets look into a simple example between 2 Salesforce Orgs

OrgA with a Visualforce tab acting as Client App.

OrgB acting as target salesforce server from where we need to get authorized and fetch data.

I will refer these as OrgA and OrgB through out the post.

Lets take a look into our client application (which is a visualforce page tab)

image

When you hit Fetch JWT Token button on that page, You should expect an access token along with other parameters issued by a our salesforce OrgB (or) as highlighted "https://oceans11-dev-ed.my.salesforce.com"

Lets talk code now.

I will split the flow into 6 steps for simplicity.

  1. Create a JWT
  2. Create a Certificate and private key.
  3. Upload the Certificate in connected app of your target OrgB
  4. Upload the private key in Files of your Client OrgA
  5. Request for access token
  6. Salesforce Grants Access Token

1. Create a JWT

JWT is JSON Web Token. It consists of header and claims.
JWT header should look like this

{"alg":"RS256"}
Enter fullscreen mode Exit fullscreen mode

alg - algorithm you are using

It firstly consists of claims, it should be of this format.

{
"iss": "3MVG99OxTyEMCQ3gNp2PjkqeZKxnmAiG1xV4oHh9AKL_rSK.BoSVPGZHQ
ukXnVjzRgSuQqGn75NL7yfkQcyy7", 
"sub": "my@email.com", 
"aud": "https://login.salesforce.com", 
"exp": "1333685628"
}
Enter fullscreen mode Exit fullscreen mode

lets see what do we have here... These are called JWT Claims.

iss - OAuth client_id
sub - username of the target org you are connecting to
aud - url you would want to connect. if thats a sandbox then use test instead of login.
exp - time to expire the token.

You have to Base64url encode the JWT Header and the encoded JWT Claims Set separately without any line breaks.

Next, Create a string for the encoded JWT Header and the encoded JWT Claims Set in this format

Encoded JWT Header+ "." + Encoded JWT Claims
Enter fullscreen mode Exit fullscreen mode

It would look something like this (before the dot(.) we have the header in encoded format )

eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiAiM01WRzk5T3hUeUVNQ1EzZ05wMlBqa3FlWkt4bm1BaUcxeFY0b0hoOUFLTF9yU0su
Qm9TVlBHWkhRdWtYblZqelJnU3VRcUduNzVOTDd5ZmtRY3l5NyIsICJwcm4iOiAibXlAZ1NjI4In0=
Enter fullscreen mode Exit fullscreen mode

Please refer to generateJsonBody and combineJWTHeader_Claimset method for the logic using apex code provided in the Git Repo link at the end of this post.

Now we have the JWT claims & header , lets see step 2

2. Create a Certificate and private key.

This flow requires a digital certificate and the private key used to sign the certificate.

Please feel free to use your own private key and certificate issued by a certification authority.

Alternatively, you can use OpenSSL to create a key and a self-signed digital certificate.

Refer this on How to create a Digital Certificate

Once you have completed this step,

3. Upload the Certificate in connected app of your target OrgB

We would need to upload this digital certificate to the connected app in OrgB that is also required for the JWT bearer authorization flow.

image

4. Upload the private key in Files of your Client OrgA

and create the payload to access the token

As You already have the private key file which you obtained while creating the self signed open ssl certificate, we use it to sign the request

Since this is a salesforce org, I have uploaded it in a File and retrieved it using the ContentVersion object.

Sign the resulting string using RSA SHA256.
Create a string of the string from this step in the following format.

the combined JWT string + "." + base64_encoded_signature
Enter fullscreen mode Exit fullscreen mode

See retrievePKContent and signPkey method from the Git repo link which

the base64 encoded signature should be something like this (I have clipped the content for keeping it small).

eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiAiM01WRzk5T3hUeUVNQ1EzZ05wMlBqa3FlWkt4bm1BaUcxeFY0b0hoOUFLTF9yU0su
Qm9TVlBHWkhRdWtYblZqelJnU3VRcUduNzVOTDd5ZmtRY3l5NyIsICJwcm4iOiAibXlAZ1NjI4In0=.iYCthqWCQucwi35yFs-nWNgpF5NA_a46fXDTNIY8ACko6BaEtQ9E6h4Hn1l_pcwcK​
I_GlmfUO2dJDg1A610t09TeoPagJsZDm_H83bsoZUoI8LpAA1s-2a​
36y2L2Bh7M8TNWiKa_BNM6s1FNKDAwHEWQrNtAeReXgRy0MZgQY2rZtqT2FcDyjY3JVQb​
En_CSjH2WV7ZlUwsKHqGfI7hzeEvVdfOjH9NuaJozxvhPF489IgW6cntPuT2V647JWi7ng
Enter fullscreen mode Exit fullscreen mode

5. Request for Access Token.

Next, Once you have the entire base64encoded string , make a callout to the token endpoint of the target org ORGB in this case.

the endpoint should look like this

https://login.salesforce.com/services/oauth2/token?grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion='+YOUR-ENTIRE-JWT-VALUE STRING YOU PREPARED '
Enter fullscreen mode Exit fullscreen mode

This should be a POST call.

6. Salesforce grants access token.

once done, if everything is place correctly, You should see a response with access token.

If we see the Visualforce page above, that gives you the below result.
image

If you observe the image, I got the access token, I can see all the scopes and the id corresponds to the user id and org id
and the token type which is bearer.

Using this token you can easily access the data of the Target OrgB

Please find the complete code in GIT Link HERE
Please do not commit any changes to main

Hope this post helps someone who is trying to understand the JWT with salesforce or is trying to implement it.

See you again with a new post.

Discussion (0)

pic
Editor guide