AWS S3 uploading an object which is publicly readable

Viewed 557

I am using the AWS v2 java SDK. I am trying to upload an object to my bucket. I want the object to be publicly readable.

What I have done is as follows:

     PresignedPutObjectRequest presignedRequest =S3Presigner.create()
                .presignPutObject(z -> z.signatureDuration(Duration.ofMinutes(10))
                    .putObjectRequest(
                                por -> por.bucket("MYBUCKET")
                                    .key("MYOBJECTKEY")
                                    .acl(ObjectCannedACL.PUBLIC_READ)));
   URL url = presignedRequest.url(); 

I then use this URL to upload a file. I am getting a 403 response when I do this.

If I remove the line adding the acl, then the upload works.

If I change the ACL to PRIVATE, that too fails.

From my aws console, I can make an object public, so I dont think that it is a bucket policy problem.

How can this be fixed? I want to upload an object to a bucket and make it publicly readable

After some more debugging from my end, it looks to be a problem with the way the URL is being built.
This is part of the URL when I dont add an ACL

&X-Amz-SignedHeaders=host&X-Amz-Expires=120  

And this is the similar part of the URL with an ACL

&X-Amz-SignedHeaders=host%3Bx-amz-acl&X-Amz-Expires=120  

It looks like the URL building gets borked

2 Answers

For the sake of completeness, the code snippet to upload the object while setting the public read header is as follows

HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "text/plain");
connection.setRequestProperty("x-amz-acl", "public-read");
connection.setRequestMethod("PUT");
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write("This text uploaded as an object via presigned URL.");  
out.close();  

The key part is

connection.setRequestProperty("x-amz-acl", "public-read");
Related