Using JWT to Authenticate to Box from SnapLogic

SnapLogic has a Box Snap Pack which works very well for the majority of day to day Box operations. The snaps are easy to use and connecting to Box using the Box Account is very simple. I would recommend using this Snap Pack if the snaps meet your needs. However, the Box snaps (at this writing) won’t allow you to take advantage of the full functionality that the Box API provides. So, to access the additional functionality will require the use of the SnapLogic REST snaps.

When I decided to investigate the possibility of using the Box REST api, the first decision that I had to make was how to authenticate to Box. Box provides multiple options for authentication, but OAuth2 with JWT turned out to be the clear choice because it connects server-to-server without any user interaction. Unfortunately, however, using OAuth2 with JWT presented several challenges for me.

I confess that most of the challenges were due to my ignorance about JWT and SSL. I spent a lot of time researching both of these technologies. If you don’t already have a good understanding of how JSON Web Tokens work, then it would be a good idea for you to read up on them. I found this site to be particularly helpful; https://jwt.io/introduction/.

My first challenge came in the fact that Box and SnapLogic use different ways to manage the SSL Keys that are necessary to sign the JWT. SnapLogic uses a Java Keystore (jks) where Box uses Privacy Enhanced Mail (pem) keys. As I discovered, converting from jks to pem is really not that difficult, but the documentation in Box assumes you are using pem and doesn’t address jks at all. The reverse is true for SnapLogic.

My second challenge was in figuring out what data should be included in the JWT and where to put the data within the JWT Generate snap.

If you’re also struggling with some of these challenges, I hope the steps below can save you some time.

Before you start, you’ll need the following;

  • The JWT Snap Pack installed in your SnapLogic environment.
  • An installation of the Java Runtime Environment (jre).
  • An installation of OpenSSL. I used the Cygwin package suggested by Box on their JWT Application Setup page.
  • Access to the Box enterprise account, either directly or through a system administrator.

Create an OAuth2 with JWT authenticated app in Box
You can read in the Box documentation about how to do this, it’s a pretty simple process.
When you get to the “Add and Manage Public Keys” section, follow the instructions below to generate your own public/private keypair. This is not the Box recommended method, but it is the only way that I could find to generate both the JKS and PEM files needed by SnapLogic and Box.

Create the Java Keystore and Public Key PEM files
keytool.exe -genkey -keyalg rsa -keystore .jks -alias
keytool.exe -export -keystore .jks -file .der -alias
openssl.exe x509 -in .der -inform der -outform PEM -pubkey -noout > .pem

Add the Public Key to Box
In your Box app, under the “Add and Manager Public Keys” section, click the “Add a Public Key” button. Then, copy the entire contents of the public key PEM file (created in the previous step) and paste it into the Public Key area, then click the “Verify and Save” button.

Change the Alias of the Java Keystore
Note: At the time of this writing, SnapLogic erroneously associates the key alias with the key id (kid) attribute in the JWT header, thus requiring us to make them the same. The key id is assigned by Box when we add the public key to the app. Since we have no control over the Public Key that Box chooses, we must change the alias of the keystore to match our Box app’s Public Key ID.

keytool.exe -changealias -alias -destalias -keystore .jks

Download the App Settings from Box
Use the “Download as JSON” button at the bottom of the app config page to get a copy of the app settings. (We’ll use this later.)

Grant Access to the Application in Your Box Enterprise
Instructions for this are in the Box docs at https://developer.box.com/docs/setting-up-a-jwt-app under Step 3.

Upload the JKS file and App Settings to the sldb or another storage location accessible by SnapLogic
Use the SnapLogic Manager tab to upload files to the SnapLogic Database (sldb) if you want to store the files there, or you can store them on FTP, AWS S3, Google, etc.

Create a JWT Account to Sign the JWT
Go to the SnapLogic Manager tab and add a new JWT Account to your project. Set the Key Store to the location of your jks file then enter the KeyStore password and Key Alias (i.e. the Pubic Key Id from your Box App). Use the Validate button to verify that everything is working then apply the changes.

Create the Authentication Pipeline in SnapLogic
Create a pipeline in SnapLogic which will generate the JWT, send it to Box for authentication, and return the Bearer Token.
Add and configure the following snaps in the pipeline.

  1. A File Reader snap to load the app settings Json.

  2. A JSON Parser snap to parse the app settings.

  3. A Mapper snap to format the JWT Claims.
    image

  4. A JWT Generate snap to create the JSON Web Token.
    image

NOTE: Be sure to go to the Account tab and select the JWT Account that we created earlier.

  1. A Mapper snap to build the token request.
    image

Here is the full Expression for the encodedUri.
‘grant_type=’+encodeURIComponent(‘urn:ietf:params:oauth:grant-type:jwt-bearer’)+’&client_id=’+encodeURIComponent($original.claims.iss)+’&client_secret=’+encodeURIComponent($original.clientSecret)+’&assertion=’+encodeURIComponent($access_token)

1 Like

(Here is the rest of the pipeline. I exceeded the maximum number of images in the first part.)

  1. A REST Post snap to send the token request to Box.
    image

I also added an HTTP header for the Content-type. (Not sure if this is necessary, but it can’t hurt.)
image

  1. A Mapper snap to retrieve the Bearer Token from the response.
    image

The completed pipeline should look something like this.
image

Use the authentication pipeline to get a token and make an API call

Add a Pipeline Execute snap to execute the Authentication Pipeline that we just created and a REST snap to make the call with the Bearer token returned.
image

2 Likes

Cool topic, but also a bummer to have to do all of that. Not sure if you have too, but we raised an enhancement request with SnapLogic to somehow allow the use of the BOX Account from the BOX Snap Pack for other BOX REST APIs that don’t have BOX snaps. We already have that BOX Account configured, and SnapLogic is already managing the refresh of the OAuth keys, so seems there should be a way to grab and use that key for a regular REST snap. Or maybe a generic BOX API snap.

Allowing the BOX Account to be used with the REST snaps would be great! It would be a very simple solution to the problem. Perhaps my solution will be short lived, which wouldn’t bother me at all. Until then, I hope my efforts will provide some usefulness.