Skip to Content
Technical Articles
Author's profile photo Deepak Jaiswal

ServiceNow (SNOW) connectivity using Oauth grant_type “password” in SAP Cloud Integration

Introduction:

In a requirement where we need to connect SAP Cloud Integration( SAP CPI) with ServiceNow Instance for creation of case/Incident. We need to call the ServiceNow APIs to authenticate via several authentication mechanism few of them are Basic Authentication(username and password) and Oauth Authentication.

Now, in this blog , I am going to demonstrate how we can use Oauth Connectivity between SAP Cloud Integration (SAP CPI) and ServiceNow using grant_type = “Password”.

While demonstrating the step by step process, we may go through few important technical aspects as below:

  1. Leveraging Security Artifacts–> User Credential type to store Username,Password,Client ID and Client Secret which I have used as a trick to avoid exposure of connectivity details over iflow build steps.
  2. Setting up of Authorization Header body using credentials from above step1 and setting content type “application/x-www-form-urlencoded” through a groovy script.
  3. Use of Authentication bearer token by setting up Auth Token Header using a groovy script which will be used to send data/file attachment to ServiceNow API for incident creation.
  4. Capturing HTTP response body received from ServiceNow incident/case creation using a groovy script.

This sample process can be leveraged by developers to edit, modify and enhanced according to other business requirements as well.

Prerequisites:

You should have CPI tenant access and have understanding on Integration flow development.

You should have ServiceNow OAuth details like Username,Password,ClientID,Client Secret to be configured on CPI tenant.

Design approach: To explain these scenario, I have created sample iflow:

Below Figure1 will show the high level steps performed on the iflow development

Figure 1 : Iflow Steps

 

Step1(Figure1) : Sender System(Participants) : This System name is defined to connect to Sender system SFTP to poll the file.

Step2(Figure1) : Sender SFTP Channel to Poll the files to be sent to ServiceNow API for incident creation. Files to be picked up from Sender SFTP folder path as configured.

Step3(Figure1) : Content Modifier in this usecase used to set properties for below externalized parameters like:

Filename : To get the polled filename

FilePath : Archive folder path for polled files to move.

SYS_ID : for ServiceNow API parameter

SnowCredential : To specify the security artifact name

inputfilepayload : To store input file payload body.

Content%20Modifier%20-%20Externalization%20of%20Parameters

Content Modifier – Externalization of Parameters

 

Here Property SnowCredential¬† : “testServiceNow2″ is defined on Security artifacts as User Credential type to avoid exposure of password,clientid and client secret to be hardcoded on the Iflow.(this is one of the trick I have used to configure and retrieved on groovy script on next step).

Developers can explore more ways of hiding secure connectivity credentials details and post as blog comments.

 

Security%20Artifacts%20-%20User%20Credential%20Type

Security Artifacts – User Credential Type

 

Step4(Figure1) :Groovy Script : This step is used to retrieve Username, Client_Id, Client_Secret from Deployed Security Artifact ” testServiceNow2″ and prepare an authorization body for Oauth grant_type = “Password” connectivity and this body will be passed on the next step via HTTP channel for authentication request with ServiceNow instance.

On this groovy script message header Content-type is also set to “application/x-www-form-urlencoded” which is required for making successful authentication.

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import com.sap.it.api.ITApiFactory;
import com.sap.it.api.securestore.SecureStoreService;
import com.sap.it.api.securestore.UserCredential;

def Message processData(Message message) {
    


//Credentials // the same user credentials needs to be avaliable in secure material.
//def user = "YOUR_UserCredentials";
def user = message.getProperty("SnowCredential");// externalise to provide different name configured in other instances on transport
message.setHeader("Content-type", "application/x-www-form-urlencoded");

//service to get the credentials
def service = ITApiFactory.getApi(SecureStoreService.class, null);

//get user credential
def userCred = service.getUserCredential(user);
if (userCred == null){
throw new IllegalStateException("No User credential found for alias" + user);
}

String username = userCred.getUsername();
String password = new String(userCred.getPassword());


//store password parameters i.e password client id and client secret delimited with * symbol as mentioned on respective security artifact
String[] entry = password.split("\\*"); 
password = entry[0].trim();// retrive password
client_id = entry[1].trim(); // retrive cleint Id
client_secret = entry[2].trim(); // retrive Client_secret


//HTTP Parameters value
String grant_type = "password"; // Service Now grant type

//Query
def query = "";
query = query + "client_id=" + client_id + "&";
query = query + "client_secret=" + client_secret + "&";
query = query + "grant_type=" + grant_type + "&";
query = query + "username=" + username + "&";
query = query + "password=" + password;

message.setBody(query);


return message;
}

Groovy Script Code Snippet (Prepare Authentication Body and set content-type message header)

 

Step5/Step6/and Step7 (Figure1) : Request Reply/ServiceNow Receiver component/HTTP Channel: These steps are used to call ServiceNow system using HTTP adapter which tries to authenticate with prepared Authentication body and prepared Content-Type on step 4:

HTTP%20Channel%20for%20OAuth%20Authentication%20Request

HTTP Channel for OAuth Authentication Request

Here, Http Address format is “ https://<ServiceNowInstance-Address>/Oauth_token.do

Where, <ServiceNowInstance-Address> = Service now instance connectivity address.

 

Step8(Figure1) :Groovy Script : This step is used to retrieve the the response from ServiceNow and store the Auth bearer token generated and configured as Authorization Header parameter after successful authentication from last step.

ServiceNow session remains open for this authenticated token until timeout. This token authenticate directly for further data transfer(in our case sending incoming file) through ServiceNow API until token session expired at ServiceNow side.

import groovy.json.*;
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {
    //Body 
       def body = message.getBody(String.class);
       def jsonSlurper = new JsonSlurper()
       def list = jsonSlurper.parseText(body)
       def token="Bearer "+list.access_token.toString();
       //Headers 
       def map = message.getHeaders();
       message.setHeader("Authorization", token);
      
       return message;
}

Groovy Script Code Snippet (Prepare Authorization Header from generated authentication Token)

Step9(Figure1) : Content Modifier : This step is used to retrieve incoming payload body of the polled file.

Content%20Modifier%20-%20Get%20Incoming%20payload

Content Modifier – Get Incoming payload

 

Step10/Step6/and Step11 (Figure1) : Request Reply/ServiceNow Receiver component/HTTP Channel: These steps are used to call the actual ServiceNow API for incident creation.

It will internally make use of set Token Authorization Header to authenticate and pass the incoming payload/data to ServiceNow system.

Sending%20File%20to%20ServiceNow%20API%20for%20incident/Case%20creation

Sending File to ServiceNow API for incident/Case creation

Here, URL configured is :

https://<ServiceNow-Address>/api/now/attachment/file?table_name={property.SYS_tablename}&table_sys_id=${property.SYS_ID}&file_name=${property.Filename}

Where:{property.SYS_tablename} , ${property.SYS_ID},${property.Filename} are externalized parameter for user inputs screen.

 

Step12/Step13(Figure1) :Groovy Script/end : This step is used to retrieve the the response from ServiceNow final API call and log the HTTP response and end the process.

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;

def Message processData(Message message) 
{
	def body = message.getBody(java.lang.String) as String;
	def messageLog = messageLogFactory.getMessageLog(message);
	if(messageLog != null)
	{
	messageLog.addAttachmentAsString("HTTP Response after attachment upload:", body, "text/plain");
     }
	return message;
}

Conclusion:

In this blog post, I demonstrated how to make use of Oauth grant_type = password based connectivity leveraging below points:

  1. How to retrieve Oauth credential parameters using groovy script from Security artifacts User Credential type and a trick used to maintain password as combination of password, clientId, client_secret delimited with character(in my usecase it’s a “*” star-symbol).
  2. Set Authentication Body and Content- type using script for initial ServiceNow instance authentication.
  3. Creating an Authorization header from Service Now Bearer token retrieved.
  4. Calling the ServiceNow API for transmitting data using Authorization Token header .
  5. Capturing the HTTP response from ServiceNow API call.

Hope this blog post will help CPI developers to achieve similar functionality and this can be enhanced more to meet the technical business requirements.

Assigned Tags

      4 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Madhubala Chandran
      Madhubala Chandran

      Hi Deepak ,

      Good and useful blog . Thanks for this knowledge sharing ..

       

      Author's profile photo Vimal Pillai
      Vimal Pillai

      Excellent blog Deepak.. The explanation has the depth to enable a novice person perform the ServiceNow integration.. Brilliant!!!

      Author's profile photo Vidyadhar Kurmala
      Vidyadhar Kurmala

      Hi Deepak,

      We can implement caching and use refresh_token grant type to get a new token.. However w.r.t this link ROPC is NOT a recommended approach. Best practice is to implement Auth Code grant type and as of today SAP Cloud Integration supports Authorization code grant type with Microsoft as a provider. Hence I have used open connectors to connect with ServiceNow using auth code grant type with ServiceNow as provider.

      Thanks,

      Vidyadhar K

      Author's profile photo rshashi rshashi
      rshashi rshashi

      Explained well, good one Deepak. keep posting.