英文:
AWS Java SDK 2.0 S3 presigned URL public object access
问题
在自身创建预签名 URL 进行文件上传方面是正常工作的。
但是通过默认生成的 URL 上传文件会使其默认为私有,因此无法通过其 URL 访问。
我必须手动转到控制台,将文件设置为公开,才能通过其 URL 访问。
以下是您的代码:
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("上传文件的预签名 URL: " +
presignedRequest.url());
System.out.println("上传文件时需要使用的 HTTP 方法: " +
presignedRequest.httpRequest().method());
presigner.close();
在 Node.js 中,我们指定希望文件可以公开访问,因此我找到了其 Java SDK 的等效代码,如下所示:
PutObjectRequest objectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(keyName)
.acl(ObjectCannedACL.PUBLIC_READ)
.build();
但是,通过生成的 URL 进行上传时,我收到了签名不匹配的错误:
我们计算的请求签名与您提供的签名不匹配。请检查您的密钥和签名方法。
我做错了什么?难道这不是使文件公开访问的正确方法吗?如果不是,我应该如何操作?
英文:
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?
答案1
得分: 2
我在AWS的java-sdk的GitHub页面上发布了相同的问题,并找到了解决方案。
在PutObjectRequest.builder()
中添加.acl(ObjectCannedACL.PUBLIC_READ)
将在标头中添加x-amz-acl
,而不是在需要的查询中添加。
以下是如何在查询中添加它的方式:
AwsRequestOverrideConfiguration override = AwsRequestOverrideConfiguration.builder()
.putRawQueryParameter("x-amz-acl", "private")
.build();
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(keyName)
.overrideConfiguration(override)
.build();
这个解决方案完美地解决了问题。希望能对其他人有所帮助。
欲了解更多信息,请参阅github链接。
英文:
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
答案2
得分: 0
这应该可以解决问题:
new PutObjectRequest("xxx", "xxx", fis, metadata).withCannedAcl(CannedAccessControlList.PublicRead));
英文:
This should do the trick:
new PutObjectRequest("xxx", "xxx, fis, metadata).withCannedAcl(CannedAccessControlList.PublicRead));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论