我正在尝试使用IAM创建到Rekognition端点的授权签名。在Postman中使用Postman的内部 * AWS Signature * 可以正常工作,但是尝试生成Authorization Header + Signature(在PHP中)并手动输入它被证明是不可能的。
我已经看了以下问题和答案:
- Signature Version 4 Signing Process in PHP to access API Gateway endpoint
- How do you calculate an AWS signature in PHP?
- AWS Signature creation using PHP
- How do I hash the canonical request in aws4 using php to match what is expected by amazon aws sp api?
- https://github.com/avi-wish/aws4-signature-php
这些解决方案似乎对我都不起作用。我想做的是有一个PHP函数,生成授权头,日期头等,并将其粘贴到Postman,让它返回一个结果。
不管我尝试什么组合(省略payload,添加payload,添加param,省略params),我都得到:The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
是的,我已经检查了Access键,PHP脚本和Postman中的数据是相同的JSON-它与Postman的“AWS Signuature”一起工作
但是下面会不行吗?
我在这里尝试的代码:
function sign_request($url, $data) {
$host = 'rekognition.eu-west-2.amazonaws.com';
$access_key = '<<Acess_Key>>';
$secret_key = '<<Secret_Key>>';
$region = '<<Region>>';
$service = 'rekognition';
$current = new DateTime('UTC');
$current_date_time = $current->format('Ymd\THis\Z');
$current_date = $current->format('Ymd');
$signed_headers = [
'content-type' => 'application/x-amz-json-1.1',
'host' => $host,
'x-amz-date' => $current_date_time,
'x-amz-target' => 'RekognitionService.DetectFaces'
//'x-amz-security-token' => $token, // leave this one out if you have a IAM created fixed access key - secret pair and do not need the token.
];
$signed_headers_string = implode(';', array_keys($signed_headers));
$canonical = [
'POST',
parse_url($url, PHP_URL_PATH),
parse_url($url, PHP_URL_QUERY),
];
foreach ($signed_headers as $header => $value) {
$canonical[] = "$header:$value";
}
$canonical[] = '';
$canonical[] = $signed_headers_string;
$canonical[] = hash('sha256', http_build_query($data));
$canonical = implode("\n", $canonical);
$credential_scope = [$current_date, $region, $service, 'aws4_request'];
$key = array_reduce($credential_scope, fn ($key, $credential) => hash_hmac('sha256', $credential, $key, TRUE), 'AWS4' . $secret_key);
$credential_scope = implode('/', $credential_scope);
$string_to_sign = implode("\n", [
'AWS4-HMAC-SHA256',
$current_date_time,
$credential_scope,
hash('sha256', $canonical),
]);
$signature = hash_hmac('sha256', $string_to_sign, $key);
unset($signed_headers['host']);
$signed_headers['Authorization'] = "AWS4-HMAC-SHA256 Credential=$access_key/$credential_scope, SignedHeaders=$signed_headers_string, Signature=$signature";
return $signed_headers;
}
$requestUrl = 'https://rekognition.eu-west-2.amazonaws.com/?Action=DetectFaces';
$body = [
"Attributes"=> [
"ALL"
],
"Image"> [
"Bytes"=> "<<BASE64_of_Face_Image>>"
]
];
print_r(sign_request($requestUrl, $body ));
我错过了什么吗?
1条答案
按热度按时间zvms9eto1#
我通过将
x-amz-content-sha256
添加到上面的$signed_headers
数组来使它工作。标题也必须按字母顺序排列,如下所述:https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html部分StringToSign
需要说明的是,StringtoSign和CanonicalRequest中需要哈希负载
Amazon doc上面:
The x-amz-content-sha256 header is required for all AWS Signature Version 4 requests. It provides a hash of the request payload. If there is no payload, you must provide the hash of an empty string.
新代码: