What format should be used to request the API without an error to screen Chinese name?

Options

These are some information you may like to know:


Error message returned: org.springframework.web.client.HttpClientErrorException: 401


request url: https://rms-world-check-one-api-pilot.thomsonreuters.com/v1/cases/screeningRequest


httpEntity: <{"customFields":[],"entityType":"INDIVIDUAL","groupId":"0a3687d0-693a-1414-9a6d-52c700001613","name":"张三","providerTypes":["WATCHLIST"],"secondaryFields":[{"typeId":"SFCT_1","value":"MALE"},{"dateTimeValue":{"pointInTimePrecision":"DAY","timelinePrecision":"ON","utcDateTime":-485600400000},"typeId":"SFCT_2"},{"typeId":"SFCT_5","value":"HKG"}]},{Date=[5 Dec 2019 03:17:12 GMT], Authorization=[Signature keyId="4eeea3fb-d10a-4521-b083-229ed9dce00b",algorithm="hmac-sha256",headers="(request-target) host date content-type content-length",signature="Ngt2S9g3oWJ/v4vkHKCSohlzg9q1tExTkBsgf9sghHo="], Content-Length=[349], Content-Type=[application/json]}>


Response : HTTP Status Code 401

Best Answer

Answers

  • @terrence.lim

    This question has been answered before in this portal.

    Please have a look at the link below. This will help you understand how to screen chinese characters successfully.

    https://community.developers.refinitiv.com/questions/50476/401-unauthorized-when-calling-worldcheck-with-name.html?childToView=50477#answer-50477


  • Tried and it is still not working.

  • @terrence.lim

    Request you to share the code snippets with comments so that I can see how are you sending the screening request with special characters.

  • @Override public WdProcessParamsDto apply(WordCheckContextDto wordCheckContextDto,

    WordCheckInputParamsDto wordCheckInputParamsDto) {

    WdCaseAPIReqDto caseAPIReqDto = buildRequestCaseParams(wordCheckContextDto, wordCheckInputParamsDto);

    //The content body

    String requestJSONParams = JSON.toJSONString(caseAPIReqDto);

    int length = EscapeUtils.unescape(URLEncoder.encode(requestJSONParams)).length();


    //get timestamp

    String currentDateOfGmtValue = new Date().toGMTString();

    String dataToSign = "(request-target): post " + configurationProperties.getGatewayUrl() + "cases/screeningRequest\n" + "host: "

    + configurationProperties.getGatewayHost() + "\n" + "date: " + currentDateOfGmtValue + "\n"

    + "content-type: application/json\n" + "content-length: " + length + "\n" + requestJSONParams;

    //See below

    String hmac = SecretUtils.generateSha256(configurationProperties.getSecret(), dataToSign);


    String authorisation = "Signature keyId=\"" + configurationProperties.getApiKey()

    + "\",algorithm=\"hmac-sha256\",headers=\"(request-target) host date content-type content-length\",signature=\""

    + hmac + "\"";


    WdProcessParamsDto paramsDto = new WdProcessParamsDto();

    paramsDto.setCallURL(MessageFormat.format(APIURL, configurationProperties.getProtocol(),

    configurationProperties.getGatewayHost(), configurationProperties.getGatewayUrl()));


    paramsDto.setHeadAuthorization(authorisation);

    paramsDto.setHeadDate(currentDateOfGmtValue);


    paramsDto.setExtParams(() -> {

    Map<String, Object> map = new HashMap<>(2);

    map.put("Content-Length", length);

    map.put("Content-Data", requestJSONParams);

    return map;

    });


    return paramsDto;

    }

    //SecretUtils.generateSha256

    public static String generateSha256(String secret, String message) {

    String hash = "";

    try {

    Mac sha256_HMAC = Mac.getInstance("HmacSHA256");

    SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");

    sha256_HMAC.init(secret_key);

    hash = Base64.encodeBase64String(sha256_HMAC.doFinal(message.getBytes()));


    } catch (Exception e) {

    System.out.println("Error");

    }

    return hash;

    }

  • @terrence.lim

    I see that you are using the below code to calculate the length:

    int length = EscapeUtils.unescape(URLEncoder.encode(requestJSONParams)).length(); 

    You can use the below code instead of the above:

    int length = EscapeUtils.unescape(URLEncoder.encode(requestJSONParams,"UTF-8")).length(); 

    Also, I see that you are not passing the UTF-8 enccoded JSON payload in the API request but the content of the variable requestJSONParams. Please UTF-8 encode the payload before sending it over. Please check point 5 in my first reply.

    map.put("Content-Data", requestJSONParams); 


  • Tried and same error.

    Also, our project's encoding is utf-8

  • Edited and tried the following also not resolving the issue

    map.put("Content-Data", URLEncoder.encode(requestJSONParams,"UTF-8"));

    and

    int length = EscapeUtils.unescape(URLEncoder.encode(requestJSONParams,"UTF-8")).length();

  • @terrence.lim

    Instead of the below code:

    URLEncoder.encode(requestJSONParams,"UTF-8"));

    Can you try the below:

    HttpEntity entity= new StringEntity(requestJSONParams,Charsets.UTF-8);

    Request you to provide me the complete request headers and response headers so that I can trouble shoot.

    Kindly compare the Base64 encoded HMAC signature and content lenght generated by your code to that of the one generated by Postman to know if your signature is correct. You can do this by executing your code first, then pick up the date header value from your code and paste in the pre request script of Postman to generate the HMAC (obviously the request will fail as the date header value is obsolete but you should get the same HMAC signature). Compare both to know if they match.

  • It is still not working.

  • @terrence.lim

    Let us get into a phone call to resolve this.

    Please provide me a good time (with time zone) so that I can send you a webex invite.

  • Hi Irfan, finally we managed to resolve the matter. Thanks again for your support.

  • @terrence.lim Can you please help us with the solution so that it helps our other community members who have the same issue?