【问题标题】:SignatureDoesNotMatch error when posting to AWS S3 presign url发布到 AWS S3 presign url 时出现 SignatureDoesNotMatch 错误
【发布时间】:2018-02-27 15:58:50
【问题描述】:

真的在这个问题上苦苦挣扎,所以任何帮助都会很棒!

所以我尝试使用预签名的 url 直接从浏览器将 pdf 文件上传到 Amazon S3。

我使用 AWS Java SDK(用 Kotlin 编写的代码)在服务器上生成 url,如下所示:

    val objectKey = StringBuilder().append("xxx").append("/").append("file1.pdf").toString()

    val expiration = java.util.Date()
    var msec = expiration.time
    msec += (1000 * 60).toLong() // Add 1 minute. This means that the url expires in 1 minute.
    expiration.time = msec

    String bucketName = "test"

    val responseHeaders = ResponseHeaderOverrides().withContentType("multipart/form-data")

    val generatePresignedUrlRequest = GeneratePresignedUrlRequest(bucketName, objectKey)
    generatePresignedUrlRequest.method = HttpMethod.POST
    generatePresignedUrlRequest.responseHeaders = responseHeaders
    generatePresignedUrlRequest.expiration = expiration

    return s3Client.generatePresignedUrl(generatePresignedUrlRequest)

这个 url 然后返回给使用 Angular 的浏览器代码。 然后我使用以下打字稿代码直接上传文件:

returnPresignUrl() {
   return this.http.get(this.attachmentUploadUrl, this.httpOptions);

}

   uploadFiletoS3(file, filetype) {
       let presignURL;
       const data = file;
       const fileHeaders = {
           headers: new HttpHeaders({
               'Content-Type': 'multipart/form-data',
           })
       };
       this.returnPresignUrl().subscribe(url => {
           presignURL = url;
           this.http.post(presignURL, data, 
fileHeaders).subscribe((res) => {
               console.log('File uploaded', res);
           }, (error) => { console.log('Error uploading File', error); 
});
       }, (error) => { console.log('Error getting a preasign URL: ', 
error); });
   }

但我得到以下错误响应:

<Code>SignatureDoesNotMatch</Code>
<Message>
    The request signature we calculated does not match the signature you 
provided. Check your key and signing method.
</Message>

有什么想法吗?

我在 presign url 中指定内容类型标头,然后还在对 url 的发布请求中设置它,所以我看不到标头不匹配的情况(一个似乎导致问题的错误我看到了)。

发帖请求有什么特别之处吗? 将 pdf 文件上传到 S3 的内容类型是否正确?

任何见解都会很棒,谢谢!

【问题讨论】:

  • 您能检查一下您的访问密钥和密钥吗?当您的密钥也无效时,您会收到此错误。
  • Java SDK 表示应该使用 setMethod(HttpMethod 方法),支持的方法有 GET、PUT、DELETE、HEAD。使用放置。此外,通常您可能应该使用 setResponseHeaders() 之类的 setter 方法。
  • 当我将其更改为 PUT 时,我收到拒绝访问错误。有任何想法吗?访问密钥和密钥不应该包含在其中,因为使用预签名 URL 的全部意义在于我们不需要在浏览器中存储安全凭证。
  • 另外,这是 Kotlin 代码,记住,直接引用字段并设置它与调用 set() 方法相同
  • 好的,现在你得到了 AccessDenied,你已经解决了最初的问题。您的预签名 URL 是否过期?客户端时间同步了吗?

标签: angular amazon-web-services amazon-s3 kotlin pre-signed-url


【解决方案1】:

使用: generatePresignedUrlRequest.setContentType("application/octet-stream");

而不是: multipart/form-data

这是我生成预签名 URL 的方法:

public GeneratePresignedUrlRequest getGeneratePresignedUrlRequest(String tempBucketName,String objectKey){
    Date expirationTime = getExpirationTime();
    GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(tempBucketName, objectKey);
    generatePresignedUrlRequest.setMethod(HttpMethod.PUT);
    generatePresignedUrlRequest.setExpiration(expirationTime);
    generatePresignedUrlRequest.setContentType("application/octet-stream");
    return generatePresignedUrlRequest;
}

当你调用 put 调用上传文件时,你应该使用相同的 Content-Type。

【讨论】:

    猜你喜欢
    • 2019-04-29
    • 1970-01-01
    • 2012-05-02
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-13
    相关资源
    最近更新 更多