我有一个需要上传文件到S3的播放应用程序。我们正在开发scala并使用Java AWS SDK。亚马逊S3签名不匹配 - AWS SDK Java
我在尝试上传文件时遇到问题,在使用预先登录的网址时,我不断收到403 SignatureDoesNotMatch。网址是正在使用AWS的Java SDK通过下面的代码genereated:
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。
该上传文件(相同于本文中使用的一个)
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凭证和JS的功能尝试更改请求标头。我总是得到相同的结果。 亚马逊为什么告诉我签名不匹配?
好答案!注意:如果你想为S3的响应设置Content-Type头(即当AWS将响应发送回客户端时),你必须创建一个ResponseHeaderOverrides的新实例,在* that *上调用setContentType()然后在您的GeneratePresignedUrlRequest实例上调用setRequestHeaders(RequestHeaderOverrides)。在GeneratePresignedUrlRequest实例上调用setContentType会导致上述问题的另一个变体 - 由S3接收到的HTTP请求与预先登记的请求不同。 –
更新的文档可在以下网址找到:http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html –
我从未在一百万年内了解到这一点。谢谢 – user2465134