Using the java Amazon AWS SDK, I am getting an unexplainable 403 AccessDenied exception when calling the AmazonS3Client.getObject()
method. What is odd here is that I am uploading the object with the same AmazonS3Client
so the object resource owner should be the same.
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
Even if I specify an ACL with the putObject()
call, I still get the AccessDenied exception.
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!!!
I’ve tested this by including an ACL with Grantee ALL_USERS to the amazonS3.putObject()
call and this allows me to use the amazonS3.getObject()
call okay without any exceptions so it seems like a permissions issue somewhere. But where?!
The Amazon docs specifically say that a resource owner has access to the resource: "By default, all Amazon S3 resources—buckets, objects, and related subresources (for example, lifecycle configuration and website configuration)—are private: only the resource owner, an AWS account that created it, can access the resource.”
Edit
I should have mentioned originally that I am using the RiakCS client to connect to S3. At the time of this edit, it seems to be an issue with RiakCS.
Most likely your Riak CS S3 endpoint either does not support or is not configured for AWS v4 signatures. GetObject seems to be special in that respect as it per default uses a v4 signature in the current SDK version.
What you can do is configure the client to use v2 signatures instead:
ClientConfiguration opts = new ClientConfiguration();
opts.setSignerOverride("S3SignerType"); // NOT "AWS3SignerType"
AmazonS3Client s3 = new AmazonS3Client(opts);
see discussion here: https://github.com/aws/aws-sdk-java/issues/372