无法解释的 AmazonS3Client getObject() 403 AccessDenied 异常
Unexplainable AmazonS3Client getObject() 403 AccessDenied exception
使用 java Amazon AWS SDK,调用 AmazonS3Client.getObject()
方法时出现无法解释的 403 AccessDenied 异常。奇怪的是我用相同的 AmazonS3Client
上传对象,所以对象资源所有者应该是相同的。
ClientConfiguration config = new ClientConfiguration();
config.setProtocol(Protocol.HTTP); // TODO Change to HTTPS?
AWSCredentials awsCredentials = new BasicAWSCredentials("myAccessKeyID","mySecretAccessKey");
AmazonS3 amazonS3 = new AmazonS3Client(awsCredentials, config);
amazonS3.setEndpoint(serviceInfo.getHost());
S3ClientOptions options = new S3ClientOptions();
options.setPathStyleAccess(true);
amazonS3.setS3ClientOptions(options);
amazonS3.putObject(“myBucket”, “keyVal”, file);
amazonS3.getObject(“myBucket”, “keyVal”); //AccessDenied
即使我在 putObject()
调用中指定了 ACL,我仍然会收到 AccessDenied 异常。
Owner owner = amazonS3.getS3AccountOwner();
AccessControlList acl = new AccessControlList();
acl.grantPermission(new CanonicalGrantee(owner.getId()), Permission.Read);
amazonS3.putObject(new PutObjectRequest("mybucket", "myKey", f).withAccessControlList(acl));
amazonS3.getObject(“myBucket”, “keyVal”); //AccessDenied Still!!!
我已经通过在 amazonS3.putObject()
调用中包含一个带有 Grantee ALL_USERS 的 ACL 来对此进行测试,这让我可以毫无例外地使用 amazonS3.getObject()
调用,所以看起来某个地方的权限问题。但是在哪里?!
Amazon 文档特别指出资源所有者可以访问该资源:
“默认情况下,所有 Amazon S3 资源——存储桶、对象和相关子资源(例如,生命周期配置和网站配置)——都是私有的:只有资源所有者,即创建它的 AWS 账户,才能访问该资源。”
编辑
我本来应该提到我正在使用 RiakCS 客户端连接到 S3。在编辑时,这似乎是 RiakCS 的问题。
在 Amazon S3 控制台中,如果您导航到特定文件夹,您会在 "properties" 选项卡下找到 "permissions" 折叠菜单。您需要将 grantee 设置为 "Everyone" 并选中必要的复选框。
很可能您的 Riak CS S3 端点不支持或未配置 AWS v4 签名。 GetObject 在这方面似乎很特别,因为它在当前 SDK 版本中默认使用 v4 签名。
您可以将客户端配置为使用 v2 签名:
ClientConfiguration opts = new ClientConfiguration();
opts.setSignerOverride("S3SignerType"); // NOT "AWS3SignerType"
AmazonS3Client s3 = new AmazonS3Client(opts);
使用 java Amazon AWS SDK,调用 AmazonS3Client.getObject()
方法时出现无法解释的 403 AccessDenied 异常。奇怪的是我用相同的 AmazonS3Client
上传对象,所以对象资源所有者应该是相同的。
ClientConfiguration config = new ClientConfiguration();
config.setProtocol(Protocol.HTTP); // TODO Change to HTTPS?
AWSCredentials awsCredentials = new BasicAWSCredentials("myAccessKeyID","mySecretAccessKey");
AmazonS3 amazonS3 = new AmazonS3Client(awsCredentials, config);
amazonS3.setEndpoint(serviceInfo.getHost());
S3ClientOptions options = new S3ClientOptions();
options.setPathStyleAccess(true);
amazonS3.setS3ClientOptions(options);
amazonS3.putObject(“myBucket”, “keyVal”, file);
amazonS3.getObject(“myBucket”, “keyVal”); //AccessDenied
即使我在 putObject()
调用中指定了 ACL,我仍然会收到 AccessDenied 异常。
Owner owner = amazonS3.getS3AccountOwner();
AccessControlList acl = new AccessControlList();
acl.grantPermission(new CanonicalGrantee(owner.getId()), Permission.Read);
amazonS3.putObject(new PutObjectRequest("mybucket", "myKey", f).withAccessControlList(acl));
amazonS3.getObject(“myBucket”, “keyVal”); //AccessDenied Still!!!
我已经通过在 amazonS3.putObject()
调用中包含一个带有 Grantee ALL_USERS 的 ACL 来对此进行测试,这让我可以毫无例外地使用 amazonS3.getObject()
调用,所以看起来某个地方的权限问题。但是在哪里?!
Amazon 文档特别指出资源所有者可以访问该资源: “默认情况下,所有 Amazon S3 资源——存储桶、对象和相关子资源(例如,生命周期配置和网站配置)——都是私有的:只有资源所有者,即创建它的 AWS 账户,才能访问该资源。”
编辑
我本来应该提到我正在使用 RiakCS 客户端连接到 S3。在编辑时,这似乎是 RiakCS 的问题。
在 Amazon S3 控制台中,如果您导航到特定文件夹,您会在 "properties" 选项卡下找到 "permissions" 折叠菜单。您需要将 grantee 设置为 "Everyone" 并选中必要的复选框。
很可能您的 Riak CS S3 端点不支持或未配置 AWS v4 签名。 GetObject 在这方面似乎很特别,因为它在当前 SDK 版本中默认使用 v4 签名。
您可以将客户端配置为使用 v2 签名:
ClientConfiguration opts = new ClientConfiguration();
opts.setSignerOverride("S3SignerType"); // NOT "AWS3SignerType"
AmazonS3Client s3 = new AmazonS3Client(opts);