Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any way to use presigned URL uploads and enforce tagging?

Is there any way to issue a presigned URL to a client to upload a file to S3, and ensure that the uploaded file has certain tags? Using the Python SDK here as an example, this generates a URL as desired:

s3.generate_presigned_url('put_object', 
                          ExpiresIn=3600,
                          Params=dict(Bucket='foo', 
                                      Key='bar', 
                                      ContentType='text/plain', 
                                      Tagging='foo=bar'))

This is satisfactory when uploading while explicitly providing tags:

$ curl 'https://foo.s3.amazonaws.com/bar?AWSAccessKeyId=...&Signature=...&content-type=text%2Fplain&x-amz-tagging=foo%3Dbar&Expires=1538404508' \
  -X PUT
  -H 'Content-Type: text/plain' \
  -H 'x-amz-tagging: foo=bar' \
  --data-binary foobar

However, S3 also accepts the request when omitting -H 'x-amz-tagging: foo=bar', which uploads the object without tags. Since I don't have control over the client, that's… bad.

I've tried creating an empty object first and tagging it, then issuing the presigned URL to it, but PUTting the object replaces it entirely, including removing any tags.

I've tried issuing a presigned POST URL, but that doesn't seem to support the tagging parameter at all:

s3.generate_presigned_post('foo', 'bar', {'tagging': '<Tagging><TagSet><Tag><Key>Foo</Key><Value>Bar</Value></Tag></TagSet></Tagging>'})
$ curl https://foo.s3.amazonaws.com/ \
  -F key=bar \
  -F 'tagging=<Tagging><TagSet><Tag><Key>Foo</Key><Value>Bar</Value></Tag></TagSet></Tagging>'
  -F AWSAccessKeyId=... \
  -F policy=... \
  -F signature=... \
  -F file=@/tmp/foo

<Error><Code>AccessDenied</Code><Message>Invalid according to Policy:
Extra input fields: tagging</Message>...

I simply want to let a client upload a file directly to S3, and ensure that it's tagged a certain way in the process. Any way to do that?

like image 786
deceze Avatar asked Oct 01 '18 14:10

deceze


People also ask

How secure are pre signed URLs?

Pre-signed URLs can be generated for an S3 object, allowing anyone who has the URL to retrieve the S3 object with an HTTP request. Not only is this more secure due to the custom nature of the URL, but the available options also allow you to set an expiration on the URL, the default being one hour.

What is the main advantage to a pre signed URL?

A presigned URL gives you access to the object identified in the URL, provided that the creator of the presigned URL has permissions to access that object.

When should I use Presigned URL S3?

Pre-signed URLs are used to provide short-term access to a private object in your S3 bucket. They work by appending an AWS Access Key, expiration time, and Sigv4 signature as query parameters to the S3 object. There are two common use cases when you may want to use them: Simple, occasional sharing of private files.

Should I use Presigned URL?

Yes, Pre-signed URL's are used to grant temporary access to s3 object for a particular amount of time. Apart from this, you can use pre-signed URL's to grant url receiver the access to upload files to s3.


1 Answers

Try the following code:

fields = {
    "x-amz-meta-u1": "value1",
    "x-amz-meta-u2": "value2"
}
conditions = [
    {"x-amz-meta-u1": "value1"},
    {"x-amz-meta-u2": "value2"}
]


presignedurl = s3_client.generate_presigned_post(
    bucket_name, "YOUR_BUCKET_NAME",
    Fields=copy.deepcopy(fields),
    Conditions=copy.deepcopy(conditions)
)
like image 169
Reza Mousavi Avatar answered Sep 20 '22 20:09

Reza Mousavi