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 réponse
0
Réponse acceptée

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
EXPERT
James_S
répondu il y a un an
  • 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.

Vous n'êtes pas connecté. Se connecter pour publier une réponse.

Une bonne réponse répond clairement à la question, contient des commentaires constructifs et encourage le développement professionnel de la personne qui pose la question.

Instructions pour répondre aux questions