Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call S3 pre-signed URL with postman

I am attempting to use a pre-signed URL to upload as described in the docs (https://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObject.html) I can retrieve the pre-signed URL but when I attempt to do a PUT in Postman, I receive the following error:

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

Obviously, the way my put call is structured doesn't match with the way AWS is calculating the signature. I can't find a lot of information on what this put call requires.

I've attempted to modify the header for Content-Type to multipart/form-data and application/octet-stream. I've also tried to untick the headers section in postman and rely on the body type for both form-data and binary settings where I select the file. The form-data setting results in the following added to the call:

Content-Disposition: form-data; name="thefiletosend.txt"; filename="thefiletosend.txt

In addition, I noticed that postman is including what it calls "temporary headers" as follows:

Host: s3.amazonaws.com Content-Type: text/plain User-Agent: PostmanRuntime/7.13.0 Accept: / Cache-Control: no-cache Postman-Token: e11d1ef0-8156-4ca7-9317-9f4d22daf6c5,2135bc0e-1285-4438-bb8e-b21d31dc36db Host: s3.amazonaws.com accept-encoding: gzip, deflate content-length: 14 Connection: keep-alive cache-control: no-cache

The Content-Type header may be one of the issues, but I'm not certain how to exclude these "temporary headers" in postman.

I am generating the pre-signed URL in a lambda as follows:

    public string FunctionHandler(Input input, ILambdaContext context)
    { 
        _logger = context.Logger;
        _key = input.key;
        _bucketname = input.bucketname;

        string signedURL = _s3Client.GetPreSignedURL(new GetPreSignedUrlRequest()
        {
            Verb = HttpVerb.PUT ,
            Protocol = Protocol.HTTPS,
            BucketName = _bucketname,
            Key = _key,
            Expires = DateTime.Now.AddMinutes(5)
        });

        returnObj returnVal = new returnObj() { url = signedURL };

        return JsonConvert.SerializeObject(returnVal);

    }
like image 617
user2149161 Avatar asked Nov 29 '22 05:11

user2149161


1 Answers

Your pre-signed url should be like https://bucket-name.s3.region.amazonaws.com/folder/filename.jpg?AWSAccessKeyId=XXX&Content-Type=image%2Fjpeg&Expires=XXX&Signature=XXX

You can upload to S3 with postman by

  1. Set above url as endpoint
  2. Select PUT request,
  3. Body -> binary -> Select file
like image 96
Allen Wong Avatar answered Dec 06 '22 07:12

Allen Wong