Amazon S3 Signature Does Not Match - AWS SDK Java

前端 未结 8 1893
不知归路
不知归路 2021-01-01 12:18

I have a play application that needs to upload files to S3. We are developing in scala and using the Java AWS SDK.

I\'m having trouble trying to upload files, I keep

相关标签:
8条回答
  • 2021-01-01 12:57

    If your access keys and secret keys are good but it is saying "SignatureDoesNotMAtch", check your secret key, it probably has any of some special charaters, e.g +/ - / *

    Go to aws and generate another access key, where the the secret key does not have those. Then try again :)

    0 讨论(0)
  • 2021-01-01 12:59

    Got a problem, the mime type on windows was setting the fileType to empty string and it didn't work. Just handle empty strings and add some file type.

    0 讨论(0)
  • 2021-01-01 13:02

    Doubt the OP still has a problem with this, but for anyone else who runs into this, here is the answer:

    When making a signed request to S3, AWS checks to make sure that the signature exactly matches the HTTP Header information the browser sent. This is unfortunately required reading: http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html

    However in the code above this is not actually the case, the Javascript is sending:

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

    But in the Java/Scala, s3.generatePresignedUrl is being called without passing in either of them. So the resulting signature is actually telling S3 to reject anything with a Content-Type or x-ams-acl header set. Oops (I fell for it too).

    I've seen browsers send Content-Types automatically, so even if they're not explicitly added to the header they could still be coming into S3. So the question is, how do we add Content-Type and x-amz-acl headers into the signature?

    There are several overloaded generatePresignedUrl functions in the AWS SDK, but only one of them allows us to pass in anything else besides the bucket-name, filename, expiration-date and http-method.

    The solution is:

    1. Create a GeneratePresignedUrlRequest object, with your bucket and filename.
    2. Call setExpiration, setContentType, etc, to set all of your header info on it.
    3. Pass that into s3.generatePresignedUrl as the only parameter.

    Here's the proper function definition of GeneratePresignedUrlRequest to use:

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

    The function's code on the AWS GitHub repo was also helpful for me to see how to code up the solution. Hope this helps.

    0 讨论(0)
  • 2021-01-01 13:04

    I faced a similar issue and setting the config signatureVersion: 'v4' helped solve it in my case -

    In JavaScript:

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

    Adapted from https://github.com/aws/aws-sdk-js/issues/902#issuecomment-184872976

    0 讨论(0)
  • 2021-01-01 13:09

    I faced with SignatureDoesNotMatch error using the Java AWS SDK. In my case, SignatureDoesNotMatch error occurred after upgraded maven dependencies without changes in my code (so credentials are correct and were not changed). After upgrading dependency org.apache.httpcomponents:httpclient from version 4.5.6 to 4.5.7 (actually it was upgrade of Spring Boot from 2.1.2 to 2.1.3, and there bom has specified httpclient version), code became throw exceptions while doing some AWS SDK S3 requests like AmazonS3.getObject.

    After digging into the root cause, I found that httpclient library did breaking changes with normalized URI, that affected Java AWS SDK S3. Please take a look for opened GitHub ticket org.apache.httpcomponents:httpclient:4.5.7 breaks fetching S3 objects for more details.

    0 讨论(0)
  • 2021-01-01 13:10

    Same problem for me but a different cause. I was using POST instead of PUT

    0 讨论(0)
提交回复
热议问题