FortiSOAR Knowledge Base
FortiSOAR: Security Orchestration and Response software provides innovative case management, automation, and orchestration. It pulls together all of an organization's tools, helps unify operations, and reduce alert fatigue, context switching, and the mean time to respond to incidents.
anerot-forti
Staff
Staff
Article Id 309450
Description

This article describes that when sending an API request to FortiSOAR, it is necessary to authenticate it. Several authentication methods are available:

  • Login: Typically normal FortiSOAR User (Requires 1 user seat, Do not forget to Logout).
  • HMAC: Appliances (Public/Private API Key).
  • API Key: FortiSOAR 7.5.0 minimum .

Fortinet Document Library - FSR HMAC Authentication explains the concept of creating an Identifier and proposes some sample PHP and Python scripts but Postman pre-script language is Javascript.

Scope FortiSOAR, API, Postman.
Solution

Here is a Postman collection of API requests to FortiSOAR organized by folders depending on the authentication mechanism.

Just download the collection + environment variable files and import them into Postman.

The HMAC folder includes APIs with the pre-script in javascript.

 

Here is the Javascript available in the pre-script tab of HMAC-based authenticated requests:

 

//
//This script is based on https://docs.fortinet.com/document/fortisoar/7.4.3/api-guide/797122/hmac-authentication
//

//Get URI and replace any {{my_var}} with the relevant value
var replaceVars = function(string)
{
return string.replace(/\{\{.+?\}\}/g, function(match)
{
var varName = match.substr(2, match.length - 4);
var varValue = environment[varName] || globals[varName];
return varValue ? replaceVars(varValue) : match; // recursive!
}); //Thanks to Gitfool for this replace code
}
var fulluri = replaceVars(request.url);

// Build the timestamp value YYYY-MM-DD HH:MM:SS
const currentDate = new Date();
const year = currentDate.getFullYear().toString();
const month = (currentDate.getMonth() + 1).toString().padStart(2, '0');
const day = currentDate.getDate().toString().padStart(2, '0');
const hour = currentDate.getUTCHours().toString().padStart(2, '0');
const minute =currentDate.getMinutes().toString().padStart(2, '0');
const seconde=currentDate.getSeconds().toString().padStart(2, '0');
var timestamp = `${year}-${month}-${day} ${hour}:${minute}:${seconde}`;

// Get the verb
var verb = pm.request.method;

// Build the HASHED Payload and X-CS-Data Header
var payload = pm.environment.get("pub_key");
var hashedpayload = CryptoJS.SHA256(payload).toString();
pm.request.addHeader("X-CS-Data: " + hashedpayload);

// Build the HMAC256 Fingerprint
var SecretPassphrase = pm.environment.get("priv_key");
var rawFingerprint = "sha256." + verb + "." + timestamp + "." + fulluri + "." + hashedpayload;
var hashedFingerprint = CryptoJS.HmacSHA256(rawFingerprint, SecretPassphrase).toString();

// Build the Authorization Header
var rawauth_header = "sha256;" + timestamp + ";" + payload + ";" + hashedFingerprint;
var auth_header = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(rawauth_header));
pm.request.addHeader("Authorization: CS " + auth_header);

// For debug only. Please uncomment to see some values
console.log("rawFingerprint:"+rawFingerprint,"rawauth_header:"+rawauth_header);