Hi I'm using the sample code for WorldCheck One API (https://developers.refinitiv.com/customer-and-third-party-screening/world-check-one-api/downloads) to try replicate for use on WorldCheck One Zero Footprint. However I'm having 401 unauthorised.
The same code, if I replace the api key/secret & url to that of WorldCheck One, works.
Also I've tested my API secret/key URL & groupId using postman, it works.
The one difference I've found between WorldCheck One API & WorldCheck One Zero Footprint from the Postman predefined configuration is this in the pre-request script:
For WorldCheck One:
var dataToSign = "(request-target): post " + environment["gateway-url"] + "cases/screeningRequest\n" +
"host: " + environment["gateway-host"] + "\n" +
"date: " + date + "\n" +
"content-type: " + environment["content"] +"\n" +
"content-length: " + contentLength + "\n" +
content;
For WorldCheck One Zero Footprint:
var dataToSign = "(request-target): post " + environment["zfs-gateway-url"] + "cases/screeningRequest\n" +
"host: " + environment["zfs-gateway-host"] + "\n" +
"date: " + date + "\n" +
"content-type: " + environment["content"] +"\n" +
"content-length: " + contentLength;
The Zero footprint one doesn't seem to append "content" at the end.
This is the C# code from (https://developers.refinitiv.com/customer-and-third-party-screening/world-check-one-api/downloads) which I'm trying to adapt to use for Zero Footprint. Can anyone point me in the right direction as to where I'm going wrong?
DateTime dateValue = DateTime.UtcNow; // get the datetime NOW GMT
string date = dateValue.ToString("R"); // WC1 header requires GMT datetime stamp
//Console.WriteLine(date);
//set host and credentials to the WC1 API Pilot server WC1SampleClientAPI account
string apikey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
string apisecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
string gatewayurl = "/v1/";
string gatewayhost = "zfs-world-check-one-api-pilot.thomsonreuters.com"; string requestendpoint = "https://zfs-world-check-one-api-pilot.thomsonreuters.com/v1/cases/screeningRequest";
string postData = "{ \"groupId\":\"XXXXXXXXXXXXXXXXXXXXXX\", \"entityType\": \"INDIVIDUAL\", \"providerTypes\": [ \"WATCHLIST\" ], \"name\": \"Smith\", \"secondaryFields\":[] }";
//Console.WriteLine(postData.Length);
string msg = postData;
//Console.WriteLine(msg);
UTF8Encoding encoding = new UTF8Encoding();
byte[] byte1 = encoding.GetBytes(postData);
// Assemble the POST request - NOTE every character including spaces have to be EXACT
// for the API server to decode the authorization signature
string dataToSign = "(request-target): post " + gatewayurl + "cases/screeningRequest\n" +
"host: " + gatewayhost + "\n" + // no https only the host name
"date: " + date + "\n" + // GMT date as a string
"content-type: " + "application/json" + "\n" +
"content-length: " + byte1.Length + "\n" +
msg;
Console.WriteLine("---api secret---");
Console.WriteLine(apisecret);
Console.WriteLine("---dataToSign---");
Console.WriteLine(dataToSign);
Console.WriteLine("string hmac = generateAuthHeader(dataToSign, apisecret);");
// The Request and API secret are now combined and encrypted
string hmac = generateAuthHeader(dataToSign, apisecret);
// Assemble the authorization string - This needs to match the dataToSign elements
// i.e. requires host date content-type content-length
//- NOTE every character including spaces have to be EXACT else decryption will fail with 401 Unauthorized
string authorisation = "Signature keyId=\"" + apikey + "\",algorithm=\"hmac-sha256\",headers=\"(request-target) host date content-type content-length\",signature=\"" + hmac + "\"";
Console.WriteLine("---Hmac---");
Console.WriteLine(hmac);
//Console.WriteLine(authorisation);
// Send the Request to the API server
HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(requestendpoint);
// Set the Headers
WebReq.Method = "POST";
WebReq.Headers.Add("Authorization", authorisation);
WebReq.Headers.Add("Cache-Control", "no-cache");
WebReq.ContentLength = msg.Length;
WebReq.Date = dateValue; // use datetime value GMT time
// Set the content type of the data being posted.
WebReq.ContentType = "application/json";
WebReq.ContentLength = byte1.Length;
Stream newStream = WebReq.GetRequestStream();
newStream.Write(byte1, 0, byte1.Length);
// Get the Response - Status OK
HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();
// Status information about the request
Console.WriteLine(WebResp.StatusCode);
Console.WriteLine(WebResp.ResponseUri);
// Get the Response data
Stream Answer = WebResp.GetResponseStream();
StreamReader _Answer = new StreamReader(Answer);
string jsontxt = _Answer.ReadToEnd();
// convert json text to a pretty printout
var obj = Newtonsoft.Json.JsonConvert.DeserializeObject(jsontxt);
var f = Newtonsoft.Json.JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented);
Console.WriteLine(f);
Console.WriteLine("Press any key");
Console.ReadKey(); // pause for any key
}
public static string generateAuthHeader(string dataToSign, string apisecret)
{
byte[] secretKey = Encoding.UTF8.GetBytes(apisecret);
HMACSHA256 hmac = new HMACSHA256(secretKey);
hmac.Initialize();
byte[] bytes = Encoding.UTF8.GetBytes(dataToSign);
byte[] rawHmac = hmac.ComputeHash(bytes);
Console.WriteLine("---rawHmac---");
string hex = BitConverter.ToString(rawHmac).Replace("-", "");
Console.WriteLine(hex);
return (Convert.ToBase64String(rawHmac));
}