Springboot Java AuthorisationHeader error 401 for Linux
Hi, My name is Jorge and I'm trying to connect with World check API. The issue is: we are always getting a 401 authorisation error, but just for linux.
We have our service running in windows and we dont have any issue running it in our local environment (Windows).
When we deploy it to our DEV environment which is in Linux we are getting a 401 error, the same keys, the same code, without any change.
We already tried some different logics. Seems to be a problem with break line - "\n" in the Data to Sign string. We tried "\n" or System.lineSeparator().
//we need to keep System.lineSeparator for linux, we cannot put "\n" directly in the string.
String breakLine = System.lineSeparator();
switch (method){
case GET:
requestDataToSign = "(request-target): get " + gatewayUrl + path + breakLine +
"host: " + gatewayHost + breakLine +
"date: " + date;
break;
case POST:
requestDataToSign = "(request-target): post " + gatewayUrl + path + breakLine +
"host: " + gatewayHost + breakLine +
"date: " + date;
if(StringUtils.hasLength(bodyString)){
requestDataToSign +=
breakLine + "content-type: " + MediaType.APPLICATION_JSON_VALUE + breakLine +
"content-length: " + contentLength + breakLine +
bodyString;
requestDataHeaders=Constants.REQUEST_HEADERS_WITH_BODY;
}
}
log.debug("Request sign {}", requestDataToSign);
return signRequestData(requestDataToSign,requestDataHeaders,apiKey,apiSecret);
private String signRequestData(String dataToSign, String requestHeaders, String apiKey, String apiSecret) {
String hmac = generateAuthHeader(dataToSign, apiSecret);
return "Signature keyId=\"" + apiKey + "\",algorithm=\"hmac-sha256\",headers=\"(request-target) " + requestHeaders + "\",signature=\"" + hmac + "\"";
}
private String generateAuthHeader(String dataToSign, String apiSecret)
{
String hash = "";
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);
log.info("Charset.defaultCharset().toString() {}" , Charset.defaultCharset().toString());
hash = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(dataToSign.getBytes(StandardCharsets.UTF_8)));
}
catch (Exception e){
log.error(e.getMessage(), (Object[]) e.getStackTrace());
}
return(hash);
}
How do you suggest to create this Authorization String? to work in windows and linux.
Would be great if it's possible to have a teams call to be easier to show and communicate this issue. We are struggling with this and we have a data for the deploy.
Thank you
Jorge Medina
Best Answer
-
Hi @jorgemedina
Thanks for sharing the requested details.
When you get the 401 which means that the request has failed an authorization check. This can happen for a variety of reasons, such as an invalid or expired API key, an invalid HMAC signature or a request timing issue/problem with the Date header value.
Therefore, I have validated your Linux request header and response header and found out that the clock is not synchronized as you can see that there is ~2 minutes difference between the request header and the response header (it shouldn't be more than 30 seconds), hence you are getting the 401 error. You should ensure a correctly synchronized clock is used to generate request timestamps.Thanks
Vivek Kumar Singh0
Answers
-
Hi @jorgemedina
Thanks for reaching out to us!We are working with our internal team on above reported issue. We will get back to with our findings Shortly.
In the meantime, can you please help us with the "Complete request header and Response header"
Thanks
Vivek Kumar Singh0 -
Hi Kumar,
Sure,
Windows:
---> GET https://api-worldcheck.refinitiv.com/v2/groups HTTP/1.1
Accept: application/json
Authorization: Signature keyId="af0806ab-982c-4b42-bd2a-edd82f17b5d1",algorithm="hmac-sha256",headers="(request-target) host date",signature="XueN09p/CsTFrlDy3cOHFYj7YbuknikE0Vd8amZCdII="
Cache-Control: no-cache
Content-Type: application/json
Date: Wed, 22 Dec 2021 10:45:12 GMT
END HTTP (0-byte body)
<--- HTTP/1.1 200 (578ms)
cache-control: no-cache, no-store, max-age=0, must-revalidate
connection: keep-alive
content-type: application/json;charset=UTF-8
date: Wed, 22 Dec 2021 10:45:17 GMT
expires: 0
pragma: no-cache
strict-transport-security: max-age=15552000, includeSubdomains
transfer-encoding: chunked
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 1; mode=block
[{"id":"XXXXXXXXXXXXXXX","name":"KPMG & Associados - Sociedade de Revisores Oficiais de Contas S.A.- API - (Pilot)","parentId":null,"hasChildren":false,"status":"ACTIVE","children":[]}]Linux:
---> GET https://api-worldcheck.refinitiv.com/v2/groups HTTP/1.1
Accept: application/json
Authorization: Signature keyId="af0806ab-982c-4b42-bd2a-edd82f17b5d1",algorithm="hmac-sha256",headers="(request-target) host date",signature="UivhRONBMcIZ4EFzxLZe9JfEHc0Urp7rmTtgTpzH1yA="
Cache-Control: no-cache
Content-Type: application/json
Date: Wed, 22 Dec 2021 11:43:44 GMT
---> END HTTP (0-byte body)
<--- HTTP/1.1 401 (246ms)
authorization: WWW-Authenticate: Signature realm="World-Check One API",algorithm="hmac-sha256",headers="(request-target) host date content-type content-length"
connection: keep-alive
date: Wed, 22 Dec 2021 10:45:16 GMT
strict-transport-security: max-age=15552000, includeSubdomains
transfer-encoding: chunked
<--- END HTTP (0-byte body)The request was made to both machines, as you can see by the Date. (Our linux machine (Dev environment) is 1 hour ahead against our local environment (Windows)).
The following code is the one who trigger the first block of code in my question, where we have "String breakLine = System.lineSeparator(); ":
public void apply(RequestTemplate requestTemplate) {
//Get the current date
String date = apiAuthorisationManager.getDateHeader();
String authorisationSignatureString = "";
//Check if exist body or not in the request
String bodyString = null;
if(requestTemplate.body() != null && requestTemplate.body().length > 0){
bodyString = new String(requestTemplate.body());
}
Collection<String> contentLengthValues = requestTemplate.headers().get(HttpHeaders.CONTENT_LENGTH);
authorisationSignatureString = apiAuthorisationManager.generateAuthorisationHeader(RequestMethod.valueOf(requestTemplate.method()),
requestTemplate.path(),
date,
bodyString,
contentLengthValues != null ? contentLengthValues.stream().findFirst().orElse(null):"");
requestTemplate.header(HttpHeaders.CACHE_CONTROL, "no-cache");
requestTemplate.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
requestTemplate.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
requestTemplate.header(HttpHeaders.AUTHORIZATION, authorisationSignatureString);
requestTemplate.header(HttpHeaders.DATE, date);
}The main difference now that we have is:
"String breakLine = "\n";"
instead of
String breakLine = System.lineSeparator();
Because with "String breakLine = System.lineSeparator(); " wont work using our windows environment and either using our linux environment.
0 -
Hi Kumar,
Thank you for your time.
We thought that the Data which we have in the request header was validated against the date inside the signature string.
Yes you are right and we will work according your suggestion.
We already did some tests to confirm it, and it works.
Once again thank you for your time.
0 -
Hi @jorgemedina
Glad to know that our suggestion resolved your issue.
Thanks
Vivek Kumar Singh0
Categories
- All Categories
- 6 AHS
- 37 Alpha
- 161 App Studio
- 4 Block Chain
- 4 Bot Platform
- 16 Connected Risk APIs
- 47 Data Fusion
- 30 Data Model Discovery
- 608 Datastream
- 1.3K DSS
- 577 Eikon COM
- 4.9K Eikon Data APIs
- 7 Electronic Trading
- Generic FIX
- 7 Local Bank Node API
- Trading API
- 2.7K Elektron
- 1.3K EMA
- 236 ETA
- 519 WebSocket API
- 33 FX Venues
- 10 FX Market Data
- 1 FX Post Trade
- 1 FX Trading - Matching
- 12 FX Trading – RFQ Maker
- 5 Intelligent Tagging
- 2 Legal One
- 20 Messenger Bot
- 2 Messenger Side by Side
- 9 ONESOURCE
- 7 Indirect Tax
- 59 Open Calais
- 264 Open PermID
- 39 Entity Search
- 2 Org ID
- PAM
- PAM - Logging
- 8.4K Private Comments
- 6 Product Insight
- Project Tracking
- ProView
- ProView Internal
- 20 RDMS
- 1.4K Refinitiv Data Platform
- 367 Refinitiv Data Platform Libraries
- 3 Refinitiv Due Diligence
- LSEG Due Diligence Portal API
- 3 Refinitiv Due Dilligence Centre
- Rose's Space
- 1.1K Screening
- 18 Qual-ID API
- 13 Screening Deployed
- 23 Screening Online
- 10 World-Check Customer Risk Screener
- 990 World-Check One
- 44 World-Check One Zero Footprint
- 45 Side by Side Integration API
- Test Space
- 3 Thomson One Smart
- 1.2K TR Internal
- Global Hackathon 2015
- 2 Specialists Who Code
- 10 TR Knowledge Graph
- 150 Transactions
- 142 REDI API
- 1.7K TREP APIs
- 4 CAT
- 21 DACS Station
- 117 Open DACS
- 1.1K RFA
- 103 UPA
- 172 TREP Infrastructure
- 224 TRKD
- 886 TRTH
- 5 Velocity Analytics
- 5 Wealth Management Web Services
- 59 Workspace SDK
- 9 Element Framework
- 5 Grid
- 13 World-Check Data File
- Yield Book Analytics
- 46 中文论坛