AWS S3 Java: doesObjectExist results in 403: FORBI

2020-03-30 17:25发布

问题:

I'm having trouble with my Java program using the AWS SDK to interact with an S3 bucket.

This is the code I use to create an S3 client:

public S3StorageManager(S3Config config) throws StorageException {

   BasicAWSCredentials credentials = new BasicAWSCredentials(myAccessKey(), mySecretKey());
   AWSStaticCredentialsProvider provider = new AWSStaticCredentialsProvider(credentials);

   this.s3Client = AmazonS3ClientBuilder
        .standard()
        .withCredentials(provider)
        .withRegion(myRegion)
        .build();

When I try to download a file, before starting the download I check wether the file exists or not with:

s3Client.doesObjectExists(bucketName, objectName);

This is where I get 403: FORBIDDEN. The weird thing is this problem is raised only when I try to perform an object existence check before performing uploads in the same session. In other words, after initializing the s3Client: - if I first try to check if an object exists, it raises the FORBIDDEN problem; - if I first perform file upload, it works fine and after that any object existence check works fine as well;

Here is my stacktrace:

com.amazonaws.services.s3.model.AmazonS3Exception: Forbidden (Service: Amazon S3; Status Code: 403; Error Code: 403 Forbidden; Reques
t ID: A23BB805491E411F)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1588) ~[aws-java-sdk-core-1.
11.128.jar:?]
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1258) ~[aws-java-sdk-core-1.11
.128.jar:?]
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1030) ~[aws-java-sdk-core-1.11.128
.jar:?]
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:742) ~[aws-java-sdk-core-1.11.128.jar:
?]
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:716) ~[aws-java-sdk-core-1.11.1
28.jar:?]
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699) ~[aws-java-sdk-core-1.11.128.jar:?]
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667) ~[aws-java-sdk-core-1.11.128.jar
:?]
        at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649) ~[aws-java-sdk-core-1.1
1.128.jar:?]
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513) ~[aws-java-sdk-core-1.11.128.jar:?]
        at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4169) ~[aws-java-sdk-s3-1.11.128.jar:?]
        at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4116) ~[aws-java-sdk-s3-1.11.128.jar:?]
        at com.amazonaws.services.s3.AmazonS3Client.getObjectMetadata(AmazonS3Client.java:1237) ~[aws-java-sdk-s3-1.11.128.jar:?]
        at com.amazonaws.services.s3.AmazonS3Client.getObjectMetadata(AmazonS3Client.java:1213) ~[aws-java-sdk-s3-1.11.128.jar:?]
        at com.amazonaws.services.s3.AmazonS3Client.doesObjectExist(AmazonS3Client.java:1272) ~[aws-java-sdk-s3-1.11.128.jar:?]

Another weird thing is that all these problems started when I moved my Java program an EC2 remote machine. If I execute it on my local machine, the S3 interaction works fine. However I don't think the problem depends on the IAM roles, since I use the AWSStaticCredentialsProvider.

回答1:

Your credentials may be correct, but you will still get FORBIDDEN if you do not set the correct IAM polices. To check for objects in s3 you need the following:

{
    "Version":"2012-10-17",
    "Statement":[
        {
            "Effect":"Allow",
            "Action":[
            "s3:ListBucket"
            ],
            "Resource":["arn:aws:s3:::examplebucket/*"]
        },
        {
            "Effect":"Allow",
            "Action":[
            "s3:GetObject"
            ],
          "Resource":["arn:aws:s3:::examplebucket/*"]
        }
    ]
}


回答2:

Make sure the date time is set correctly on the machine you are making the request from, otherwise you will get a 403.



回答3:

You need an action "ListBucket" for your bucket but not for the file in your bucket like: { "Action": [ "s3:ListBucket" ], "Resource": "arn:aws:s3:::bucketName", "Effect": "Allow" }



回答4:

I really look like an IAM policy issue. What is your user's policies on your local machine vs what is your IAM role with which policy(ies)? For your EC2 instance, when you create it, create a role with "AmazonS3FullAccess" policy, if it solves the problem you'll remove the useless rights.