S3 signed URLs via the CLI for PUT using CURL?

0

The documentation says that the CLI command aws s3 presign returns a URL for a GET. Numerous posts on the web claim that they've been able to upload (PUT) using curl with these URLs. I've been unable to duplicate this. Documentation is sometimes out of date. Can anyone confirm that PUTs are NOT possible using a signed URL generated by the CLI. Or, can someone provide a canonical, recent, example of being able to do so.

已提问 1 年前3309 查看次数
1 回答
0
已接受的回答

Per the CLI's documentation, the generated presigned URLs are only usable for GETs.

I have this recipe saved for when I need to POST; if you need to PUT, you should be able to modify it to use generate_presigned_url() instead of generate_presigned_post(). Note that this uses the boto3 library with Python, so you will need to arrange to have that available for your Python install to access (e.g. pip install boto3). The output includes values formatted for both curl and httpie, which I hope will be useful.

Python script to get presigned POST URL:

import boto3
client = boto3.client("s3")

# get presigned info
# note other params can be passed here, including expiration
# see https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.generate_presigned_post
info = client.generate_presigned_post(Bucket="some-bucket", Key="filename.txt")

# print the "fields" out in the right format to feed to httpie
print(" ".join(f"{k}='{v}'" for (k, v) in info["fields"].items()))

# for curl, use this
print(" ".join(f"-F {k}='{v}'" for (k, v) in info["fields"].items()))

# confirm the URL
print(info["url"])

Below are examples of using the returned values. You will may need to remove the comment lines for your shell to be happy.

Use with httpie:

http --form -v \
  # this the the URL from Python output
  https://some-bucket.s3.amazonaws.com/ \
  # these are the copy/pasted fields from Python output
  key='filename.txt' AWSAccessKeyId='AKIA...EWS3' policy='eyJl...dfQ==' signature='RcU...XLw=' \
  # this is the file to upload
  file@local-filename.txt

Use with curl:

curl -X POST \
  # the copy/pasted fields
  -F key='filename.txt' -F AWSAccessKeyId='AKIA...EWS3' -F policy='eyJle...dfQ==' -F signature='RcU9...XLw=' \
  # the file to upload
  -F file=@local-filename.txt \
  # the URL
  https://some-bucket.s3.amazonaws.com/
profile pictureAWS
专家
James_S
已回答 1 年前
  • Wow, thanks for the detailed and prompt response! I figured I might need to use an SDK to generate one for PUT. Seems like a shortcoming in the CLI to me, though.

您未登录。 登录 发布回答。

一个好的回答可以清楚地解答问题和提供建设性反馈,并能促进提问者的职业发展。

回答问题的准则

相关内容