Reputation: 23
Creating presigned url for file upload in itself is working fine. But uploading the file through the generated URL by default makes it private and hence cannot be accessed through it's URL
I have to manually go to the console and make the file public to be accessible from it's URL
Here is my code
String bucketName = "<bucket-name>";
String keyName = "<file-name>";
S3Presigner presigner = S3Presigner.builder().region(Region.AP_SOUTH_1).build();
PutObjectRequest objectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(keyName)
.build();
PutObjectPresignRequest presignRequest = PutObjectPresignRequest.builder()
.signatureDuration(Duration.ofMinutes(3))
.putObjectRequest(objectRequest)
.build();
PresignedPutObjectRequest presignedRequest = presigner.presignPutObject(presignRequest);
System.out.println("Pre-signed URL to upload a file to: " +
presignedRequest.url());
System.out.println("Which HTTP method needs to be used when uploading a file: " +
presignedRequest.httpRequest().method());
presigner.close();
In NodeJs we specify that we want the file to be publicly accessible so I found it's java sdk equivalent like this
PutObjectRequest objectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(keyName)
.acl(ObjectCannedACL.PUBLIC_READ)
.build();
But when uploading through the URL thus generated, I'm getting a singature mismatch error
The request signature we calculated does not match the signature you provided. Check your key and signing method
What am I doing wrong? Is it not the correct way to make the file publicly accessible? If not, how should I do it?
Upvotes: 0
Views: 2439
Reputation:
This should do the trick:
new PutObjectRequest("xxx", "xxx, fis, metadata).withCannedAcl(CannedAccessControlList.PublicRead));
Upvotes: 0
Reputation: 23
I posted the same question on AWS's github for java-sdk and found the solution.
Adding .acl(ObjectCannedACL.PUBLIC_READ)
in PutObjectRequest.builder()
will add x-amz-acl
in the header as opposed to the query where it is needed
Here's how to add it in the query
AwsRequestOverrideConfiguration override = AwsRequestOverrideConfiguration.builder()
.putRawQueryParameter("x-amz-acl", "private")
.build();
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(keyName)
.overrideConfiguration(override)
.build();
The solution works perfectly. Thought it might help someone else as well
For more info, see github
Upvotes: 2