Generating Authentication Strings for Using CA Certificates with API 2.0

As described in the Authentication API documentation, an authentication token is needed to issue requests with API 2.0.  The request for a token is made to:

https://auth.anaplan.com/token/authenticate

API 2.0 supports both Basic Authentication and CA Certificates. 

Basic Authentication is achieved in the same manner it was for API 1.3. The only difference is that it is used with the authentication request to get the token, not on each individual request.

CA Certificate authentication requires that the public key and private key be used in the request to obtain an authentication token. The following steps are needed to create the request using a CA Certificate.

  •   Add the contents of the public key to the authorization header
Authorization: CACertificate {your_CA_certificate}

{you_CA_certificate} should be replaced by the contents of the public key.  This should include the contents between the "--- BEGIN CERTIFICATE ---" and "--- END CERTIFICATE ---" lines and not including them. 

  • The Content-Type header should be "application/json".
  • The body of the request should have the following json string.
{
"encodedData" : "{encodedString}",
"encodedSignedData" : "{signedString}"
}

The {encodedString} value should be a randomly generated base-64 encoded string of at least 100 bytes.

The {signedString} value is the {encodedString} value that has been signed by the private key and then base-64 encoded.  

Ideally, each time an application needs to connect to Anaplan it should generate a new random string and signed string. If this is not possible, then it can be generated once and used each time.

Examples:

  • The documentation has some sample Java code that can be added to an existing API implementation. 
  • A full python library has been published in community. This can be used as needed to develop an authentication process.
  • Below is a simple chunk of python code based on the library above that will output the strings needed as well. In this code, the path to the public key and private key files will need to be entered into the certfile and keyfile variables respectively. 

This code requires the following:

 

from base64 import b64encode
import os
import requests
from OpenSSL import crypto
import random
import string

certfile = "{path_to_public_key_file}"
keyfile = "{path_to_private_key_file}"

"""
docstring
"""
st_cert=open(certfile, 'rt').read()
cert=crypto.load_certificate(crypto.FILETYPE_PEM, st_cert)

st_key=open(keyfile, 'rt').read()
key=crypto.load_privatekey(crypto.FILETYPE_PEM, st_key)

pem = crypto.dump_certificate(crypto.FILETYPE_TEXT, cert)
print (type(pem))
random_str = os.urandom(100)
signed_str = crypto.sign(key, random_str, "sha512")

auth_headers = "'authorization': 'CACertificate %s'" % (st_cert.replace("\n", "").replace("-----BEGIN CERTIFICATE-----", "").replace("-----END CERTIFICATE-----", ""))
print(auth_headers, '\n')
encodedstr = b64encode(random_str)
signedstr = b64encode(signed_str)
print("{")
print("   'encodedData': %s " %encodedstr.decode("utf-8") )
print("   'encodedSignedData': %s" % signedstr.decode("utf-8") )
print("}")   

 

This code returns the header needed, as well as the json body needed for the authentication request. 

Authentication Header:

api header.png

json Body:

api body.png

The content in this article has not been evaluated for all Anaplan implementations and may not be recommended for your specific situation.
Please consult your internal administrators prior to applying any of the ideas or steps in this article.