html code

Box Authentication – Getting Access token Using JWT OAuth2.0 in Salesforce

This articles explains how can we authenticate in Box.com using JWT OAuth 2.0. Here is the API details in Box API documentation: https://developer.box.com/guides/authentication/jwt/without-sdk/

Box – Prerequisites

  • Box access with Admin privileges
  • Create custom app in Box. While creating the custom app select “OAuth 2.0 with JWT (Server Authentication)” as Authentication Method
  • Authorize app by Admin:
    • Goto Admin Console –> Apps –> Custom Apps –> click Authorize new app
    • Paste the Client Id of app and submit
  • Goto App –> Copy the Client Id, Client Secret, Enterprise Id. It will be used in Salesforce.

Salesforce – Prerequisites

Apex Code

A). In following implementation, we are not using standard JWT and JWS because it throws error “Signature verification error. The public key identified by \”kid\” must correspond to the private key used for signing.” So decided to do it using by our own.

B). Datetime.now does not produce correct UNIX time and it throws error: “Please check the ‘exp’ claim.” So, JWT class is used to just generate the exp parameter.

C). Unlike other JWT implementation, Box requires Client Secret in Parameter

public class BoxAuthenticationUsingJWT{
    
    public static void connectWithBox(){
        //replace with your app client id
        String clientId = '6651wi15q83qvav53jznsgdswuxxxxxx'; 
        //replace with your app client secret
        String clientSecret = '1DTfOrIQF0M2YxSKmKmk9jY5abxxxxxx'; 
        String endpoint = 'https://api.box.com/oauth2/token';
        String iss = clientId;
        String aud = endpoint;
        String sub = '334200xxx'; //replace Enterprise Id

        //Long exp = DateTime.now().addhours(-8).addSeconds(30).getTime(); // Datetime.now is returning fiff time than what need JWT token 
        Auth.Jwt jwt = new Auth.Jwt();
        jwt.setValidityLength(60);
        String jwtRequestd = jwt.toJSONString();
        Map<String, Object> m = (Map<String, Object>)JSON.deserializeUntyped(jwtRequestd);
        Long exp = (Long)m.get('exp');
        system.debug(jwtRequestd);

        system.debug(jwt.getValidityLength());
        // Start constructing the header and claims
        String jwtHeader = '{"typ":"JWT","alg":"RS256"}';

        String jwtClaims = '{"iss":"' + iss +'","jti":"'+UserInfo.getUserID()+'","box_sub_type":"enterprise","sub":"' + sub + '","aud":"' + aud + '","exp":' + exp + '}';
        system.debug(jwtClaims);
        String jwtRequest = System.encodingUtil.base64Encode(Blob.valueOf(jwtHeader)).replace('+', '-').replace('/', '_') + '.' + System.encodingUtil.base64Encode(Blob.valueOf(jwtClaims)).replace('+', '-').replace('/', '_');

        String signature = System.encodingUtil.base64Encode(Crypto.signWithCertificate('RSA-SHA256', Blob.valueOf(jwtRequest), 'jwt')).replace('+', '-').replace('/', '_');
        String signedJwtRequest = jwtRequest + '.' + signature;

        // The JWT is fully constructed, now it's time to make the call to get the access token.

        String payload = 'grant_type=' + System.EncodingUtil.urlEncode('urn:ietf:params:oauth:grant-type:jwt-bearer', 'UTF-8');
        payload += '&client_id='+clientId+'&client_secret='+clientSecret;
        payload += '&assertion=' + signedJwtRequest;


        Http httpObj = new Http();
        HttpRequest req = new HttpRequest();
        HttpResponse res;


        req.setEndpoint(endpoint);
        req.setMethod('POST');
        req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
        req.setBody(payload);

        res = httpObj.send(req);

        System.debug(res.getBody());

    }
}

Run below line in developer console to test it:

BoxAuthenticationUsingJWT.connectWithBox();

Here is Github repo link

https://github.com/ayub-ansari/SFDC-Box-Authentication-using-JWT/blob/master/BoxAuthenticationUsingJWT

1 thought on “Box Authentication – Getting Access token Using JWT OAuth2.0 in Salesforce”

Comments are closed.