gpt4 book ai didi

javascript - Amazon S3 签名不匹配 - AWS 开发工具包 Java

转载 作者:行者123 更新时间:2023-12-03 12:26:53 25 4
gpt4 key购买 nike

我有一个播放应用程序需要将文件上传到 S3。我们正在 scala 中开发并使用 Java AWS SDK。

我在尝试上传文件时遇到问题,在使用预签名网址时,我不断收到 403 SignatureDoesNotMatch。该 url 是使用 AWS Java SDK 通过以下代码生成的:

def generatePresignedPutRequest(filename: String) = {
val expiration = new java.util.Date();
var msec = expiration.getTime() + 1000 * 60 * 60; // Add 1 hour.
expiration.setTime(msec);

s3 match {
case Some(s3) => s3.generatePresignedUrl(bucketname, filename, expiration, HttpMethod.PUT).toString
case None => {
Logger.warn("S3 is not availiable. Cannot generate PUT request.")
"URL not availiable"
}
}
}

对于我们遵循的前端代码 ioncannon article .

上传文件的js函数(同文中使用的那个)
 function uploadToS3(file, url)
{
var xhr = createCORSRequest('PUT', url);
if (!xhr)
{
setProgress(0, 'CORS not supported');
}
else
{
xhr.onload = function()
{
if(xhr.status == 200)
{
setProgress(100, 'Upload completed.');
}
else
{
setProgress(0, 'Upload error: ' + xhr.status);
}
};

xhr.onerror = function()
{
setProgress(0, 'XHR error.');
};

xhr.upload.onprogress = function(e)
{
if (e.lengthComputable)
{
var percentLoaded = Math.round((e.loaded / e.total) * 100);
setProgress(percentLoaded, percentLoaded == 100 ? 'Finalizing.' : 'Uploading.');
}
};

xhr.setRequestHeader('Content-Type', 'image/png');
xhr.setRequestHeader('x-amz-acl', 'authenticated-read');

xhr.send(file);
}
}

服务器的响应是
<?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>
<StringToSignBytes>50 55 bla bla bla...</StringToSignBytes>
<RequestId>F7A8F1659DE5909C</RequestId>
<HostId>q+r+2T5K6mWHLKTZw0R9/jm22LyIfZFBTY8GEDznfmJwRxvaVJwPiu/hzUfuJWbW</HostId>
<StringToSign>PUT

image/png
1387565829
x-amz-acl:authenticated-read
/mybucketname/icons/f5430c16-32da-4315-837f-39a6cf9f47a1</StringToSign>
<AWSAccessKeyId>myaccesskey</AWSAccessKeyId></Error>

我已经配置了 CORS,仔细检查了 aws 凭据并尝试更改请求 header 。我总是得到相同的结果。
为什么亚马逊告诉我签名不匹配?

最佳答案

怀疑 OP 对此仍有问题,但对于遇到此问题的其他人来说,这是答案:

在向 S3 发出签名请求时,AWS 会检查以确保签名与浏览器发送的 HTTP header 信息完全匹配。不幸的是,这是必读的:http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html

然而,在上面的代码中,实际情况并非如此,Javascript 正在发送:

xhr.setRequestHeader('Content-Type', 'image/png');
xhr.setRequestHeader('x-amz-acl', 'authenticated-read');

但是在 Java/Scala 中,调用 s3.generatePresignedUrl 时没有传入其中任何一个。因此,生成的签名实际上是告诉 S3 拒绝任何带有 Content-Type 或 x-ams-acl header 集的内容。哎呀(我也爱上了它)。

我已经看到浏览器自动发送 Content-Types,所以即使它们没有明确添加到 header 中,它们仍然可以进入 S3。那么问题来了,我们如何将 Content-Type 和 x-amz-acl header 添加到签名中?

AWS SDK 中有几个重载的 generatePresignedUrl 函数,但其​​中只有一个允许我们传入除存储桶名称、文件名、到期日期和 http 方法之外的任何其他内容。

解决方案是:
  • 使用您的存储桶和文件名创建一个 GeneratePresignedUrlRequest 对象。
  • 调用 setExpiration、setContentType 等来设置你所有的标题信息。
  • 将其作为唯一参数传递给 s3.generatePresignedUrl。

  • 这是要使用的 GeneratePresignedUrlRequest 的正确函数定义:

    http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html#generatePresignedUrl(com.amazonaws.services.s3.model.GeneratePresignedUrlRequest)

    AWS GitHub repo 上的函数代码也有助于我了解如何编写解决方案。希望这可以帮助。

    关于javascript - Amazon S3 签名不匹配 - AWS 开发工具包 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20709711/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com