Я хочу отправить запрос на работу в Elemental MediaConvert по номеру AWS, и я читал о том, как вам нужно запрашивать конечную точку специально для вашей учетной записи и региона, поэтому я сделал, и теперь у меня есть эта пользовательская конечная точка. Я прошел процесс подписания моего запроса к этой конечной точке, которая показана здесь и здесь , но я просто не могу пройти мимо - 403 Forbidden: [{"message":"The request signature we calculated does not match the signature you provided.....
Вот то, что у меня сейчас есть:
private String MEDIA_CONVERT_ENDPOINT = "https://abcd1234.mediaconvert.us-east-1.amazonaws.com/2017-08-29/jobs";
private String MEDIA_CONVERT_HOST = "abcd1234.mediaconvert.us-east-1.amazon.com";
private String AWS_ACCESS_KEY = "AKIAXXXXXXEXAMPLE";
private String AWS_SECRET_KEY = "2AXXXXXXXXXXXX/XXXXXXXXXXXXXXX";
static byte[] HmacSHA256(String data, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException {
String algorithm = "HmacSHA256";
Mac mac = Mac.getInstance(algorithm);
mac.init(new SecretKeySpec(key, algorithm));
return mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
}
static String getSignature(String secretKey, String date, String region, String service, String stringToSign) {
byte[] kSecret, kDate, kRegion, kService, kSigning, signature;
try {
kSecret = ("AWS4" + secretKey).getBytes(StandardCharsets.UTF_8);
kDate = HmacSHA256(date, kSecret);
kRegion = HmacSHA256(region, kDate);
kService = HmacSHA256(service, kRegion);
kSigning = HmacSHA256("aws4_request", kService);
signature = HmacSHA256(stringToSign, kSigning);
} catch (Exception e) {
return "";
}
return DatatypeConverter.printHexBinary(signature).toLowerCase();
}
static String hash(String stringToEncrypt) {
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance("SHA-256");
} catch (Exception e) {
return "";
}
messageDigest.update(stringToEncrypt.getBytes(StandardCharsets.UTF_8));
return DatatypeConverter.printHexBinary(messageDigest.digest()).toLowerCase();
}
private ExecutorService executor = Executors.newFixedThreadPool(5);
public Future<APIResponse> sendJob(String jobString) {
TimeZone tz = TimeZone.getTimeZone("UTC");
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.setTimeZone(tz);
DateFormat df = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());
StringBuilder canonicalRequestBuilder = new StringBuilder("POST");
canonicalRequestBuilder.append("\n")
.append("/2017-08-29/jobs/").append("\n")
.append("\n")
.append("content-type:application/json").append("\n")
.append("host:").append(MEDIA_CONVERT_HOST).append("\n")
.append("x-amz-content-sha256:").append(hash(jobString)).append("\n")
.append("x-amz-date:").append(nowAsISO).append("\n")
.append("\n")
.append("content-type;host;x-amz-content-sha256;x-amz-date").append("\n")
.append(hash(jobString));
String hashedCanonicalRequest = hash(canonicalRequestBuilder.toString());
StringBuilder stringToSignBuilder = new StringBuilder("AWS4-HMAC-SHA256");
stringToSignBuilder.append("\n")
.append(nowAsISO).append("\n")
.append(sdf.format(date)).append("/us-east-1/mediaconvert/aws4_request").append("\n")
.append(hashedCanonicalRequest);
String signature = getSignature(
"AWS4" + AWS_SECRET_KEY,
sdf.format(date),
"us-east-1",
"mediaconvert",
stringToSignBuilder.toString()
);
Callable<APIResponse> task = () -> {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
headers.set("X-Amz-Content-Sha256", hash(jobString));
headers.set("X-Amz-Date", nowAsISO);
headers.set(
"Authorization",
"AWS4-HMAC-SHA256 Credential=" +
AWS_ACCESS_KEY +
"/" + sdf.format(date) + "/us-east-1/mediaconvert/aws4_request, " +
"SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=" + signature
);
HttpEntity<String> restRequest = new HttpEntity<>(jobString, headers);
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setReadTimeout(20000);
requestFactory.setConnectTimeout(5000);
restTemplate.setRequestFactory(requestFactory);
try {
ResponseEntity<APIResponse> response = restTemplate.exchange(MEDIA_CONVERT_ENDPOINT, HttpMethod.POST, restRequest, APIResponse.class);
return response.getBody();
} catch (Exception e) {
return new APIResponse(APIResponse.STATUS_FAILED, e.getMessage());
}
};
return executor.submit(task);
}
Я также попытался отправить запрос с помощью Postman, и это прекрасно работает, вот как выглядит CURL на Postman: ![enter image description here](https://i.stack.imgur.com/H8UQQ.png)
Я работал над этим 18 часов подряд и просто не могу понять, где я испорчил подпись. Спасибо.