How to use Secret Key Authentication with REST API?

Document ID : KB000010660
Last Modified Date : 14/02/2018
Show Technical Document Details
Introduction:

CA Service Desk Manager's REST API supports Secret Key Authentication.  This is discussed on the CA Docops pages for Service Management here: https://docops.ca.com/ca-service-management/14-1/en/reference/ca-service-desk-manager-reference-commands/technical-reference/rest-http-methods#RESTHTTPMethods-RESTSecretKeyAuthentication

However, this technical document helps with a higher level overview and other considerations that would be helpful when implementing Secret Key Authentication in SDM REST API.

 

Background:

1) Make sure communication between the client (a 3rd party program of some sort) and the SDM REST server, one should first consider implementing HTTPS between these two components. This usually means that you secure SDM REST Tomcat using an SSL certificate and use that certificate+HTTPS URL when connecting from the client

2) SDM needs to be configured to Support HMAC_ALGORITHM.  Login to SDM -> Administration tab -> Options Manager -> Web Services -> hmac_algorithm.   This option can be set to a preferred value, and install the option (In our case, we'll set it to hmacSHA1).  Follow appropriate steps that you would normally do, to install an SDM option.

3) SDM  secret_key is a 40 character alphanumeric sequence, dynamically generated by SDM during REST access key creation.  This secret_key is encrypted before it is stored in the SDM database (usp_rest_access table)

4) This secret_key needs to be used there after by the client to be able to properly authenticate itself as the valid client against the SDM REST server.

5) This is done by the client program sending a Signed Header as part of its requests from that point on.

6) The signature, a Keyed-Hash based Message Authentication Code (HMAC - Hash-based Message Authentication Code) is calculated using

  • the Secret Key
  • the header fields (eg; date, accept) provided by NX_STRING_TO_SIGN_FIELDS  (if the option is not installed) in the same order. If this option is installed
  • the cryptographic hash function provided by NX.env variable NX_HMAC_ALGORITHM (supported algorithms are HmacSHA1, HmacSHA256, HmacSHA384, HmacSHA512 and HmacMD5)
7) Client sends the request data, the signature and the Access Key to SDM.
 
8) SDM uses the Access Key to look up the Secret Key from persistence store.
 
9) SDM uses the request data and the Secret Key to generate the signature using the same hash algorithm the Client used.

 

10) If the signature generated by SDM matches the signature sent by the Client, then the request is considered authentic, otherwise the request is discarded and SDM returns an error response.
 
The installation does offer couple of samples for this under $NX_ROOT/samples/sdk/rest/java/test2_auths with README.txt under $NX_ROOT/samples/sdk/rest/java
SampleSDMAuth.java’, ‘SampleUsingSecretKey.java’ and ‘HMACUtil.java’ 
Instructions:

Below instructions were created using the Postman extension of Chrome.  For more instructions on how to use Postman, check out: https://www.getpostman.com/postman or search for Postman on Google Chrome webstore

 

1) First the client needs to obtain an access_key and secret_key from SDM REST API.  This is done by doing a POST to  /caisd-rest/rest_access

  • Set your Authorization Type to:  Basic Auth
  • Populate a Username / Password with correct values

1.JPG

  

  • Click on Update Request button

 

2) Change the Type now to  No Auth  and click the Save button

3.JPG

 

 

3) Switch to the Headers tab and ensure that the Authorization shows up as Basic with a base-64 encrypted string next to it.

2.JPG

 

4) Change just the string "Basic" to "SDM",  leave the rest of the base64 string as is (Note: there is a space character after Base,  leave that as is).  The screen should look like:

4.JPG

 

 

5) Click Save again now. 

Note: Basically , the Authorization header however, HAS to be in this format, the string "SDM" space, the base-64 encoded username/password of the SDM user.   In the above example its like this:      SDM c2VydmljZWRlc2s6aW50ZXJPUEAxMjM=

 

6) Clicking on Send now will send the POST to the SDM REST server and gives you below response from SDM:

 

POST /caisd-rest/rest_access HTTP/1.1

Host: YourSDMHostName:8553

Authorization: SDM cnVkcmEwMjpJbmRUciFwMjAxNw==

Content-Type: application/xml

x-obj-attrs: access_key,secret_key,content-type,date

Cache-Control: no-cache

 

<rest_access></rest_access>

 

RESPONSE

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<rest_access id="400502" REL_ATTR="400502" COMMON_NAME="845787692">

    <link href="http://localhost:8050/caisd-rest/rest_access/400502" rel="self"/>

    <access_key>845787692</access_key>

    <expiration_date>1503521363</expiration_date>

    <secret_key>2504166E48DC19294B86773F798DEE7996D3973E</secret_key>

 

</rest_access>

 

 

7) Now we use the secret_key as well as the access_key to make rest of the REST operations that we need. For this, we need to be able to do the HMAC encryption of the string that we need to request. This is done by creating a Pre-Request script section of Postman. For example - let us try to get some attributes from the "cnt"  object of SDM REST API.

 

var str = "GET\n/caisd-rest/cnt"

var secret = "2504166E48DC19294B86773F798DEE7996D3973E";

postman.setGlobalVariable("hmac", encodeURIComponent(CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA1(str, secret))));  

 

 

8) In the above example, the secret is the secret key we got as a response for step#6 above.  You can leave rest of the information as is. This is basically going to encrypt the resource string:  GET\n/caisd-rest/cnt   and the secret key together and encode it using the HmacSHA1 algorithm.

 

9) Go to the Authorization tab and change the Authorization to look like below instead:

SDM 845787692:{{hmac}}

 

It is literal string SDM  followed by a space, followed by the access-key from SDM that we obtained in Step#6, followed by  literal string    :{{hmac}}

 

10) Next ensure that the  GET section contains   /caisd-rest/cnt    as the resource, because that is what we are encrypting in the pre-request script anyway. 

 

11) Add the X-Obj-Attrs header key with values:  userid,last_name  (basically we are trying to get the userid, last_name field values from the resource:   /caisd-rest/cnt )

 

12) The Postman screen now looks like:

 

5.JPG

 

13) The code looks like:

 

GET /caisd-rest/cnt HTTP/1.1

Host: SDMHostName.ca.com:58553

Authorization: SDM 1842290659:jkd32qsCPwaBcWH0NX93V8zu6sI%3D

Content-Type: application/xml

X-Obj-Attrs: userid, last_name

Cache-Control: no-cache



14) Save and Send 

 

15) The response would be something like:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<collection_cnt COUNT="25" START="1" TOTAL_COUNT="36">

    <link href="http://localhost:8050/caisd-rest/cnt?start=26&amp;size=25" rel="next"/>

    <link href="http://localhost:8050/caisd-rest/cnt?start=1&amp;size=36" rel="all"/>

..

..

 

..

 <cnt id="U'793ED69B4E87A545BD8E911834D829FC'" REL_ATTR="U'793ED69B4E87A545BD8E911834D829FC'" COMMON_NAME="System_AHD_generated">

        <link href="http://localhost:8050/caisd-rest/cnt/U'793ED69B4E87A545BD8E911834D829FC'" rel="self"/>

        <last_name>System_AHD_generated</last_name>

        <userid>ahd</userid>

    </cnt>

    <cnt id="U'7A0E651346BF0E4491EBD37D13962417'" REL_ATTR="U'7A0E651346BF0E4491EBD37D13962417'" COMMON_NAME="System_Argis_User">

        <link href="http://localhost:8050/caisd-rest/cnt/U'7A0E651346BF0E4491EBD37D13962417'" rel="self"/>

        <last_name>System_Argis_User</last_name>

        <userid>System_Argis_User</userid>

 

    </cnt>

..

..

 

 

</collection_cnt>

 

 

 

 

Additional Information:

The information in this article has been included in our product documentation. You can find further details here:

https://docops.ca.com/ca-service-management/14-1/en/building/building-ca-service-desk-manager/ca-sdm-rest-api/how-to-use-the-secret-key-authentication-with-rest-api