S3 PUT请求到预签名URL的SignatureDoesNotMatch

时间:2019-03-12 03:01:06

标签: amazon-web-services amazon-s3 pre-signed-url aws-sdk-net

我正在生成服务器端的预签名URL,以允许我的客户端应用程序直接将文件上传到S3存储桶。除非客户端应用程序在计算机上运行的时区严格来说比我的服务器时钟早一天,否则一切正常。

我可以通过将系统时钟设置为第二天的时区来在本地重新创建问题。

这是我使用.NET SDK(我最初有DateTime.Now而不是UTCNow)生成预签名URL的方法:

var request = new GetPreSignedUrlRequest
{
 BucketName = bucketName,
 Key = objectName,
 Verb = HttpVerb.PUT,
 Expires = DateTime.UtcNow.AddDays(5),
 ContentType = "application/octet-stream"
};

request.Headers["x-amz-acl"] = "bucket-owner-full-control";
request.Metadata.Add("call", JsonConvert.SerializeObject(call).ToString());

return client.GetPreSignedURL(request);

然后我像这样在客户端应用程序中使用该预签名URL:

using (var fileStream = new FileStream(recordingPath, FileMode.Open))
using (var client = new WebClient())
{
    HttpContent fileStreamContent = new StreamContent(fileStream);
    var bytes = await fileStreamContent.ReadAsByteArrayAsync();
    client.Headers.Add("Content-Type", "application/octet-stream");
    //include metadata in PUT request
    client.Headers.Add("x-amz-meta-call", JsonConvert.SerializeObject(Call));

    await client.UploadDataTaskAsync(new Uri(presignedUrl), "PUT", bytes);
}

这是我从AWS收到的错误:

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>{access}</AWSAccessKeyId><StringToSign>....


在Fiddler中,这些请求看上去和我几乎一样。

作品:

PUT https://{bucketname}.s3.amazonaws.com/1c849c76-dd2a-4ff7-aad7-23ec7e9ddd45_encoded.opus?X-Amz-Expires=18000&x-amz-security-token={security_token}&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential={cred}&X-Amz-Date=20190312T021419Z&X-Amz-SignedHeaders=content-type;host;x-amz-acl;x-amz-meta-call;x-amz-security-token&X-Amz-Signature={sig} HTTP/1.1
x-amz-meta-call: {json_string}
x-amz-acl: bucket-owner-full-control
Content-Type: application/octet-stream
Host: {bucketname}.s3.amazonaws.com
Content-Length: 28289
Expect: 100-continue

{file}

不起作用:

PUT https://{bucketname}.s3.amazonaws.com/4cca3ec3-9f3f-4ba4-9d81-6336090610c0_encoded.opus?X-Amz-Expires=18000&x-amz-security-token={security_token}&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential={credentials}&X-Amz-Date=20190312T021541Z&X-Amz-SignedHeaders=content-type;host;x-amz-acl;x-amz-meta-call;x-amz-security-token&X-Amz-Signature={sig} HTTP/1.1
x-amz-meta-call: {json_string}
x-amz-acl: bucket-owner-full-control
Content-Type: application/octet-stream
Host: {bucketname}.s3.amazonaws.com
Content-Length: 18714
Expect: 100-continue


{file}

在两种情况下,预签名URL均生成相同的x-amz-date参数。我什至尝试从URL中解析出x-amz-date参数并将其显式设置为我的PUT中的标头,但这也不起作用。

我想念什么?

1 个答案:

答案 0 :(得分:0)

原来,我使用的是其他版本的签名。 v4非常适合我。

在JS中,要求S3为

const s3 = new AWS.S3({
  signatureVersion: 'v4'
});