当我尝试使用低级API(自己计算签名)向aws dynamodb发送http请求时,我收到签名不匹配异常

问题描述 投票:0回答:1

我想向 AWS DynamoDB 发送 HTTP 请求,而不使用 Salesforce B2C Commerce Cartridge 中的 AWS 开发工具包。我已遵循 AWS DynamoDB 低级 API 文档

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html

和签名版本 4 文档

https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html#example-signature-calculations

手动构造请求。但是,我遇到了“InvalidSignatureException”,并显示错误消息:我们计算的请求签名与您提供的签名不匹配。检查您的 AWS 秘密访问密钥和签名方法。有关详细信息,请参阅服务文档。'

有人可以告诉我我做错了什么吗

这是我的规范要求

const payloadObject = {
TableName: "tableName",
ReturnConsumedCapacity: "TOTAL"
}

const payload = JSON.stringify(payloadObject);
const date = new Date().toISOString().replace(/[:\-]|\.\d{3}/g, '');
const shortDate = date.substring(0, 8);
const payloadHash = crypto.createHash('sha256').update(payload).digest('hex');

const canonicalRequest = [
'POST',
'/',
'',
'action=scan',
'content-type:application/x-amz-json-1.0',
'host:dynamodb.eu-west-2.amazonaws.com',
'x-amz-content-sha256:' + payloadHash,
'x-amz-date:' + date,
'x-amz-target:DynamoDB_20120810.Scan',
'',
'content-type;host;x-amz-content-sha256;x-amz-date;x-amz-target,
payloadHash
].join('\n');

const canonicalRequestHash = crypto.createHash('sha256').update(canonicalRequest).digest('hex');

此规范请求的输出是

POST
/

action=scan
content-type:application/x-amz-json-1.0
host:dynamodb.eu-west-2.amazonaws.com
x-amz-content-sha256:4aabc25ba680a6fe0d0cadc9754a0b249b7809904c2f495b1e28ffcea826c347
x-amz-date:20231230T095237Z
x-amz-target:DynamoDB_20120810.Scan,

content-type;host;x-amz-content-sha256;x-amz-date;x-amz-target
4aabc25ba680a6fe0d0cadc9754a0b249b7809904c2f495b1e28ffcea826c347

这是我的 StringToSign

const stringToSign = [
'AWS4-HMAC-SHA256',
date,
shortDate + '/' + region + '/dynamodb/aws4_request',
canonicalRequestHash
].join('\n');

要签名的字符串的输出是

AWS4-HMAC-SHA256
20231230T095543Z
20231230/eu-west-2/dynamodb/aws4_request
2ca2fff7661d28aca561e03f48d80d53beed6d27d4422838e60ff3b006ef0f8c

这就是我如何计算文档中描述的签名(https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html#example-signature-calculations

const dateKey = crypto.createHmac('sha256', 'AWS4' + secretKey).update(shortDate).digest();
const dateRegionKey = crypto.createHmac('sha256', dateKey).update(region).digest();
const dateRegionServiceKey = crypto.createHmac('sha256', dateRegionKey).update('dynamodb').digest();
const signInKey = crypto.createHmac('sha256', dateRegionServiceKey).update('aws4_request').digest();


const signature = crypto.createHmac('sha256', signInKey).update(stringToSign).digest('hex);

最后这就是我构建授权标头的方式

const AuthorizationHeader = `AWS4-HMAC-SHA256 Credential=${accessKey}/${shortDate}/${region}/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date;x-amz-target, Signature=${signature}`;

这段代码的输出是

AWS4-HMAC-SHA256 Credential=*********/20231230/eu-west-2/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date;x-amz-target, Signature=a9043338dbb2fd574e34a0b4ffac4a291e5c7c257c50775fa76746ca8438e90b

创建所需参数后,这就是我发送请求的方式

axios.post('https://dynamodb.eu-west-2.amazonaws.com?Action=Scan', payload, {
headers: {
    'Content-Type': 'application/x-amz-json-1.0',
    'Host': 'dynamodb.eu-west-2.amazonaws.com',
    'X-Amz-Content-SHA256': payloadHash,
    'X-Amz-Date': date,
    'X-Amz-Target': 'DynamoDB_20120810.Scan',
    'Authorization': AuthorizationHeader
}
}

毕竟我从电话中得到了这个回复

{
 __type: 'com.amazon.coral.service#InvalidSignatureException',
 message: '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.'
}
javascript amazon-dynamodb
1个回答
0
投票

事实证明我在 axios post 中使用的 url 查询字符串与我在规范字符串中提供的查询字符串不匹配

在我的 canonicalString 查询字符串中是“action=scan” 但正如您在我的 axios 网址中看到的那样,它是“https://dynamodb.eu-west-2.amazonaws.com?Action=Scan”

我将 url 查询字符串更改为“https://dynamodb.eu-west-2.amazonaws.com?action=scan”并且它起作用了

© www.soinside.com 2019 - 2024. All rights reserved.