Pre-signing Amazon S3 urls for both head and get v

2019-03-12 06:36发布

问题:

I'm hosting files on Amazon S3 that I want to make accessible using pre-signed urls.

For simple GET requests this works perfectly. There are some clients however that perform a HEAD request first (to retrieve the file size). Since the signature in the URL includes the http verb (GET vs HEAD), the head request fails.

The client simply does:

HEAD http://(bucketname).s3.amazonaws.com/filename?AWSAccessKeyId=(mykey)&Expires=(timestamp)&Signature=(sig)
GET http://(bucketname).s3.amazonaws.com/filename?AWSAccessKeyId=(mykey)&Expires=(timestamp)&Signature=(sig)

I cannot change the clients to use a different url for head and get. Is there a way to make amazon use a signature that accepts both HEAD and GET for the same resource?

回答1:

You can also simulate the HEAD behavior with GET if you specify Range header for first byte only. The difference will be that you receive 206 instead of 200 code. Secondly full size will be in Content-Range header.

curl -I -H "Range: bytes=0-0" <URL>



回答2:

No. The HEAD and the GET need different signatures as there are subtle differences in the signature inputs.

Not sure what you're using to generate the pre-signed authentication URLs, but I know that some of the official AWS SDKs handle this, while others don't yet.



回答3:

with the help of a friend, I found a solution that works for me: proxy the HEAD request on my server, and redirect for the GET request.

When a request comes in with a HEAD verb to get the file info, I use my S3 code on my server to get the HEAD info and then I sent it back to the requestor myself.

When a request comes in with a GET verb to get the file itself, I do a 302 redirect with a pre-signed URL.

this works perfectly to handle both HEAD and GET by not needing to pre-sign both. I only pre-sign the GET request for the actual file.