Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
dhiraj007
Explorer
Docusign is a digital transaction platform that lets users send, sign and manage legal documents securely in the cloud. Docusign has the following authentication mechanism currently supported.

  1. Authorization code grant

  2. Implicit Grant

  3. JSON Web Token Grant


In this post, I will be demonstrating the generation of Docusign OAuth using JWT grant mechanism in cloud Integration tool. Advantages of this technique includes RSA key pair consisting of public-private key pair which provides great data security and management of large users at organizational level. The prerequisites before token generation includes following steps to be completed in Docusign Admin console.

  1. Generation of Integrator key also known as Client ID(iss).

  2. GUID format of user granting access permissions(sub).

  3. RSA public & private keys generation.


The integration flow for this process is given below.


Integration Flow


The integration flow consists of 4 basic steps.

  1. In the first step, the token properties are stored in the message property which consists of public and private key in plain text format, iss, sub, aud, exp and scope as signature impersonation as shown below.

  2. In the second step, there is a groovy code to generate JSON web token by utilizing java.security libraries as shown below.
    import com.sap.gateway.ip.core.customdev.util.Message;
    import java.util.HashMap;

    import java.io.IOException;
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.util.Date;
    import java.security.GeneralSecurityException;
    import java.security.KeyFactory;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.X509EncodedKeySpec;
    import java.security.spec.PKCS8EncodedKeySpec;

    import org.apache.commons.codec.binary.Base64;

    import com.auth0.jwt.JWT;
    import com.auth0.jwt.interfaces.DecodedJWT;
    import com.auth0.jwt.algorithms.Algorithm;

    def Message processData(Message message) {

    map = message.getProperties();
    exp = map.get("exp");
    aud = map.get("aud");
    scope = map.get("scope");
    iss = map.get("iss");
    subject = map.get("subject");
    accountNo = map.get("accountNo");
    contentType = map.get("contentType");
    accept = map.get("accept");
    privateKey = map.get("privateKey");
    publicKey = map.get("publicKey");

    java.security.Security.addProvider(
    new org.bouncycastle.jce.provider.BouncyCastleProvider()
    );

    // Read private key from property
    RSAPrivateKey privKey = getPrivateKey(privateKey);
    // Read public key from property
    RSAPublicKey pubKey = getPublicKey(publicKey);
    // Create RSA algorithm from keys
    Algorithm algorithm = Algorithm.RSA256(pubKey, privKey);
    // Get epoch time
    long currentTimeMs = System.currentTimeMillis();
    Date issuedAt = new Date(currentTimeMs);
    // Get expiration time with validity of 1 hour
    long expiryTimeMs = currentTimeMs + Integer.parseInt(exp) * 3600000;
    Date expiresAt = new Date(expiryTimeMs);
    // Create JWT for impersonation
    String token = JWT.create()
    .withIssuer(iss)
    .withSubject(subject)
    .withIssuedAt(issuedAt)
    .withExpiresAt(expiresAt)
    .withAudience(aud)
    .withClaim("scope", scope)
    .sign(algorithm);


    message.setBody(token)

    return message;
    }


    public static RSAPrivateKey getPrivateKey(String privKey) throws IOException, GeneralSecurityException {

    return getPrivateKeyFromProperty(privKey);

    }


    public static RSAPrivateKey getPrivateKeyFromProperty(String key) throws IOException, GeneralSecurityException {
    String privateKey = key;
    privateKey = privateKey.replace("-----BEGIN RSA PRIVATE KEY-----", "");
    privateKey = privateKey.replace("-----END RSA PRIVATE KEY-----", "");

    byte[] encoded = Base64.decodeBase64(privateKey);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
    RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(keySpec);
    return privKey;
    }


    public static RSAPublicKey getPublicKey(String pubKey) throws IOException, GeneralSecurityException {

    return getPublicKeyFromProperty(pubKey);
    }


    public static RSAPublicKey getPublicKeyFromProperty(String key) throws IOException, GeneralSecurityException {
    String publicKey = key;
    publicKey = publicKey.replace("-----BEGIN PUBLIC KEY-----", "");
    publicKey = publicKey.replace("-----END PUBLIC KEY-----", "");

    byte[] encoded = Base64.decodeBase64(publicKey);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(new X509EncodedKeySpec(encoded));
    return pubKey;
    }

    The following external jars has to be added in the resources section of the integration flow.


    Libraries



  3. Trigger a POST HTTP request to the Docusign authentication service with the following message body where ${in.body} is the JWT token generated from previous groovy step grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=${in.body}. Add a Content-Type header with value application/x-www-form-urlencoded.

  4. Request-Reply step to Docusign authentication service as shown below.


The integration flow has been configured and deployed successfully and now it is time to test our implementation from postman.


OAuth Token Response


As seen above, the OAuth Bearer token has been generated with expiry duration of an hour successfully for authenticating Docusign APIs. Copy the generated JWT token from the monitoring.


JWT Token


 

Now lets analyze the  JWT token generated by the script step with the help of jwt.io website.


jwt.io


So in this post we have learnt how we can generate JWT token, which we can further use to generate OAuth tokens to authenticate Docusign APIs. In the next article I will be demonstrating the steps as part of calling the envelopes API which is used in signing process for documents.

Following are the links for reference.

  1. Docusign JWT Grant Documentation -  https://developers.docusign.com/platform/auth/jwt/jwt-get-token/

  2. JWT Debugger - https://jwt.io/

  3. Integrator Key - https://www.youtube.com/watch?v=GgDqa7-L0yo

  4. Docusign Trial Account - https://go.docusign.com/o/trial/

  5. SAP BTP Products Trial - https://www.sap.com/products/free-trials

Labels in this area