Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Amazon S3 can not upload file via Cloudfront

I want to upload a file to S3 via Cloudfront with signed URL. HTTP PUT is allowed in Cloudfront Behavior. Bucket Policy

             {
        "Sid": "2",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E1C2T5UJU07REZ"
        },
        "Action": [
            "s3:PutObject",
            "s3:PutObjectAcl",
            "s3:GetObject"
        ],
        "Resource": "arn:aws:s3:::testback/*"
    }

HTTP PUT is allowed in CORS configuration. Cloudfront User also has read, writes permission. When I am trying upload file with signed URL.

curl -v -X PUT -F [email protected]  http://my-host.cloudfront.net/hello.txt?Expires=1514764800&Signature=MySig&Key-Pair-Id=My-KeyPair

I've got an error:

InvalidRequestThe authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256. 5D5DEF3D06F4583C8rBCpTUzYwm1ccc8IfkNtUnkuLxr3RZ2n7xn1j+VvP5dpG+3NMpHKPiNQ5tKpJjVliZ9UBI52vk=

Log:

2017-06-19 03:23:08 FRA54 726 My-IP PUT
my-host.cloudfront.net /hello.txt 400 -
curl/7.50.1
Expires=1514764800&Signature=My-Sig&Key-Pair-Id=My-KeyPair - Error MMHwKFzGuBzrlgP0yV71elcwEp2RVBAwJRJD1A5rO4Na6UmeKvcZPQ==
my-host.cloudfront.net http 838 0.235 - --
Error HTTP/1.1

Also, GET,DELETE works fine.

like image 992
unknown Avatar asked Jun 19 '17 03:06

unknown


1 Answers

From the CloudFront documentation:

If you're using an origin access identity and if your bucket is in one of the regions that requires signature version 4 for authentication, note the following:

DELETE, GET, HEAD, OPTIONS, and PATCH requests are supported without qualifications.

If you want to submit PUT requests to CloudFront to upload objects to your Amazon S3 bucket, you must add an x-amz-content-sha256 header to the request, and the header value must contain a SHA256 hash of the body of the request.

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html#private-content-origin-access-identity-signature-version-4

You'll need to add the hex representation of the SHA256 of the object body in an x-amz-content-sha256 request header.

It seems unexpected that CloudFront would use the inclusion of this header in a PUT as the magic trigger for internally switching to the V4 signing algorithm... but since it is mandatory for uploads, the V4 signature wouldn't be valid without it, so maybe it doesn't even try V4 (CloudFront pre-dates Signature V4). For other operations, V4 doesn't require modifications to user-agent behavior, but for PUT, it would so it would make sense for CloudFront to go with V2 as the default in its absence, even if that's wrong, so that existing code wouldn't break in places where it was already working. In any event, that seems like this should be your solution.

like image 153
Michael - sqlbot Avatar answered Nov 15 '22 15:11

Michael - sqlbot