我正在编写用于从 AWS S3 下载对象的预签名 URL。我使用 AWS Java SDK 中的 generatePresignedUrl 方法。但是,在使用生成的预签名 URL 发出 GET 请求时,我从 AWS 获得 SignatureDoesNotMatch。我很困惑,因为我使用官方 SDK 中的方法来生成它和一个非常简单的 GET 请求,但没有运气。非常感谢任何帮助!
代码(取自AWS 文档):
java.util.Date expiration = new java.util.Date();
long milliSeconds = expiration.getTime();
milliSeconds += 1000 * 60 * 60; // Add 1 hour.
expiration.setTime(milliSeconds);
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(bucketName, objectKey);
generatePresignedUrlRequest.setMethod(HttpMethod.GET);
generatePresignedUrlRequest.setExpiration(expiration);
URL url = s3client.generatePresignedUrl(generatePresignedUrlRequest);
我用于连接 AWS S3 的凭据经过测试;我能够使用来自 AWS SDK 的相同凭证和 S3 下载方法下载 S3 对象。但是我从 AWS 获得的对组合 URL 的响应(例如,https://ozland.s3.amazonaws.com/1865b563cdc94fa28ef41ee0b9b0e608?AWSAccessKeyId= ...AWSAccessKeyId...&Expires=1471300223&Signature=pbgcRB0Zg%2B3iicDQQbVX%2FqdNAAc%3D )从上面是:
<?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>...AWSAccessKeyId...</AWSAccessKeyId>
<StringToSign>GET
1471300223
/ozland/1865b563cdc94fa28ef41ee0b9b0e608</StringToSign>
<SignatureProvided>pbgcRB0Zg+3iicDQQbVX/qdNAAc=</SignatureProvided>
<StringToSignBytes>47 45 54 0a 0a 0a 31 34 37 31 33 30 30 32 32 33 0a 2f 61 6c 61 62 61 6d 61 63 6f 75 6e 74 79 2f 31 38 36 35 62 35 36 33 63 64 65 39 34 66 61 32 38 65 66 34 31 65 65 30 63 39 62 30 65 36 30 38</StringToSignBytes>
<RequestId>...RequestId...</RequestId>
<HostId>...HostId...</HostId></Error>
问题是为什么上面的 response.StringToSign 与 AWS docs ( AWS docs )描述它的方式不同。特别是,根据文档,我希望 StringToSign 像:
AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/iam/aws4_request
f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59
aws-tools非常适合我使用完全相同的 S3 存储桶和凭据生成预签名 URL。但是为什么我还是在这里得到 SignatureDoesNotMatch 呢?
谢谢!