3

I am building a web app, which should allow my app users to fetch their Salesforce data for analysis. For this, I am using OAUTH2.0 web server flow. TO avoid refresh_token related complexities, I am thinking of using JWT bearer token flow as well in my app. Basically, once user authorizes my app using OAUTH2.0 web server flow, after getting access_token for the first time from salesforce, I can follow these steps:

  1. fetch user details using access token obtained already using web server flow.
  2. build JWT token in which subject ('sub') would be username fetched in step 1.
  3. Get a new access token with which app should not need refresh token anymore.

Is this the right way to implement OAuth2.0 based 3rd party integration (Salesforce in this case) in a web app? Why?

Please help.

  • My web app needs read-only access to Salesforce data – Manu Singhal Feb 1 '18 at 8:09
3

tl;dr:
Using the JWT Bearer flow is highly unlikely to save you any trouble. Just bite the bullet and implement controls to use the refresh token flow.

full version:
The more I think about this, the more I think that using the JWT Bearer flow like this is not really a great idea. Sure, it can work, but the JWT Bearer flow comes with its own challenges.

As far as I know, the JWT Bearer flow requires that your connected app in Salesforce is set up to use a certificate ("use digital signatures"). So instead of biting the bullet, and putting in the work to use refresh tokens, you're...

  • creating a certificate
  • installing it on your server
  • uploading it for use in your connected app
  • requiring yourself to repeat this process every time your certificate expires

In my mind, this is an example of "technical debt", a decision made now in the name of speed/convenience that will make your life (or somebody's life) harder later on.

On top of that, the JWT Bearer flow isn't a panacea. One point that I think a lot of people get confused on with the JWT Bearer flow is the exp parameter. This parameter does not control when the access token you get from the flow will expire, instead, it controls how long you have to submit the JWT to Salesforce before the JWT itself becomes invalid.

The JWT flow still generates a session for your user in Salesforce (I believe that access tokens are simply <orgId>.<sessionId>), and is still subject to the timeout restrictions in your connected app (if set) or your org's default session timeout (if not set in your connected app). If a user doesn't use your connected app frequently enough (or your web app doesn't put in effort to keep the session alive), then you'll need to go through the JWT flow again to establish a new session.

At that point, you're basically performing the refresh token flow anyway (except it's more work to go through the JWT flow than it is to go through the refresh token flow).

Conclusion:
Leave the JWT Bearer flow for applications where interactivity is hard or impossible (e.g. communication between a CLI-only program and Salesforce). The web server flow with refresh tokens is more appropriate.

4

If you plan to implement an integration that requires the user to login regulary, then you can just use OAuth2 flow and invoke it whenever the user interacts with your app. However, if you intend to maintain 'long-lived' access to a user's org where you won't have the ability to interact with the user (and invoke an OAuth login), such as running background processes for extracting data and performing transformation, analysis, or whatever it is, then you will quickly find yourself in trouble thinking that "refresh_token" alone should solve your problem as noted here.

What I've been able to use consistently with minimal problems is use JWT Auth flow. Here are the steps in order to get this done:

  • Generate a key pair and self signed certificate
    • Instructions
    • Make sure you keep your private key stored safely somewhere
    • Sign your certificate to have a 3650 days (~10 year) expiration
  • Create a connected app and upload your self signed certificate
  • Get authorization from user via the normal OAuth2 method using your connected app client id and secret
    • make sure 'refresh_token' is part of the scope
    • store user's username to be used in subsequent non-interactive authorization

So whenever you have to access the user's org without user interaction, you can use JWT Auth flow by:

  • Using a library of your choice to generating a JSON Web Token
    • with the following claims
    • issuer (iss): connected app client id
    • subject (sub): user's username
    • audience (aud): either
    • expiration (exp): current time + 5 mins in Unix epoch seconds
    • signed using RS256 algorithm with your private key generated earlier
    • this is usually some functionality in your JWT library of choice so just look up RS256 signing in that library's documentation
  • request authorization
    • follow the steps documented here under "Using a JWT Bearer Token" or use a library to perform the JWT authorization
    • receive an access_token
  • use access_token to interact with the user's org just as with any other Auth flow

You may also have a hybrid application that has functionality that integrates with SF during a user's interaction with your app as well as functionality that work behind the scenes. For the in-session functionality you can just use OAuth and get an access_token from there and for the out-of-session functionality switch to JWT Auth to acquire an access_token. Beyond that, you'll have the same capabilities with either access tokens.

In case this doesn't apply to you, I'll just leave this here for others whom it might.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.