8

Here's my Java code:

        AmazonS3 conn = new AmazonS3Client();
        AmazonS3URI uri = new AmazonS3URI(s3uri);
        ObjectListing objects = conn.listObjects(uri.getBucket(), uri.getKey());

A very simple task, I try to use AmazonS3 Java client to access S3, but this line conn.listObjects keeps failing and gave me the following exception:

Exception in thread "main" com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: XXXXXXXX), S3 Extended Request ID: xxxxxxxxx
    at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1389)
    at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:902)
    at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:607)
    at com.amazonaws.http.AmazonHttpClient.doExecute(AmazonHttpClient.java:376)
    at com.amazonaws.http.AmazonHttpClient.executeWithTimer(AmazonHttpClient.java:338)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:287)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3826)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3778)
    at com.amazonaws.services.s3.AmazonS3Client.listObjects(AmazonS3Client.java:610)
    at com.amazonaws.services.s3.AmazonS3Client.listObjects(AmazonS3Client.java:588)
  1. A very obvious error code: 403 which denotes my aws credentials are wrong, however, this is exactly the same credentials that my coworkers are using to access the same s3 bucket, to rule out the possibility that I have a typo somewhere, I literally deleted my previous one and used the same one that my coworkers sent to me and put them under ~/.aws/

  2. I also researched other possible reasons, one could be that this S3 bucket doesn't give the permissions to my IAM role, apparently that is not be my case either.

Any help please? What could be the culprit?

Fisher Coder
  • 3,278
  • 12
  • 49
  • 84
  • Are you running this from an Amazon EC2 instance, or from your own computer? Can you use the [AWS Command-Line Interface (CLI)](http://aws.amazon.com/cli/) on the same machine to access Amazon S3 via the `aws s3 ls s3://bucket-name`? – John Rotenstein Mar 15 '17 at 01:25
  • I'm running on my own MacBook Pro. Yes, that's the weird part. I'm able to run that command: `aws s3 ls s3://MY-BUCKET`, so I'm so confused how is this possible. – Fisher Coder Mar 15 '17 at 01:54

2 Answers2

11

The AWS SDK for Java has a DefaultAWSCredentialsProviderChain that checks credentials in this order:

  • Environment Variables - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY (RECOMMENDED since they are recognized by all the AWS SDKs and CLI except for .NET), or AWS_ACCESS_KEY and AWS_SECRET_KEY (only recognized by Java SDK)
  • Java System Properties - aws.accessKeyId and aws.secretKey
  • Credential profiles file at the default location (~/.aws/credentials) shared by all AWS SDKs and the AWS CLI
  • Credentials delivered through the Amazon EC2 container service if AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variable is set and security manager has permission to access the variable
  • Instance profile credentials delivered through the Amazon EC2 metadata service

It is possible that your credentials are being set prior to your desired configuration file being consulted.

One way to check which credentials are being used is to use the aws iam get-user command to show the current user. You could also try that in Java with the GetUser() call.

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
  • Thanks, I've tried it, it returns this { "User": { "UserName": "MY_DEFAULT_USER_NAME", "PasswordLastUsed": "2017-03-15T01:59:05Z", "CreateDate": "2016-04-30T02:46:19Z", "UserId": "ABCDEFGHIJKLMNOPQ", "Path": "/", "Arn": "arn:aws:iam::123456789:user/MY_DEFAULT_USER_NAME" } } This is the correct user which I'm expecting. – Fisher Coder Mar 15 '17 at 04:17
  • The question is... What user does your Java program return, via the GetUser() call? Is it the same one? – John Rotenstein Mar 15 '17 at 07:03
  • Awesome, you rock! ^ ^ `GetUser()` call does return a different user, how does this happen? How could I fix this? – Fisher Coder Mar 15 '17 at 13:32
  • As per the above order, check whether Environment Variables have been set, or if there's something in the Java System Properties. Just start at the top of the list and work through it until you find the culprit. Now that you know the 'incorrect' keys, you'll recognise it when you see it. – John Rotenstein Mar 15 '17 at 21:41
  • Thanks a lot. I found 1. I have my old aws keys in my environment variables, that's why it's always wrong. 2. Later, after I remove that entry, I also needed to invalidate cache in my IntelliJ, that made my application work! Thanks a lot! – Fisher Coder Mar 17 '17 at 00:54
  • Phew! Always good to know that there is a logical explanation. The use of Environment Variables is great for testing (without having to store credentials in a file) but can be hard to notice. Good work! – John Rotenstein Mar 17 '17 at 01:00
0

If it helps anyone - I got this error because the bucket policy was set to deny when no server-side encryption was specified s3:x-amz-server-side-encryption while attempting to upload to the bucket.

alex
  • 1,905
  • 26
  • 51