AWS S3 Java:d​​oesObjectExist导致403:FORBIDDEN

时间:2017-05-30 07:50:37

标签: java amazon-web-services amazon-s3 amazon-ec2 http-status-code-403

使用AWS SDK与S3存储桶进行交互时,我的Java程序出现问题。

这是我用来创建S3客户端的代码:

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();

当我尝试下载文件时,在开始下载之前,我检查文件是否存在:

s3Client.doesObjectExists(bucketName, objectName);

这是我得到的地方403:FORBIDDEN。 奇怪的是,只有在我尝试在同一会话中执行上传之前执行对象存在检查时才会引发此问题。 换句话说,在初始化s3Client之后:   - 如果我首先尝试检查对象是否存在,则会引发FORBIDDEN问题;   - 如果我第一次执行文件上传,它工作正常,之后任何对象存在检查也可以正常工作;

这是我的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:?]

另一个奇怪的事情是,当我将Java程序移动到EC2远程计算机时,所有这些问题都开始了。 如果我在本地机器上执行它,S3交互工作正常。 但是我不认为问题取决于IAM角色,因为我使用的是AWSStaticCredentialsProvider。

4 个答案:

答案 0 :(得分:1)

您的凭据可能是正确的,但如果您未设置正确的IAM策略,您仍将获得禁止。要检查s3中的对象,您需要以下内容:

{
    "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/*"]
        }
    ]
}

答案 1 :(得分:1)

确保在您提出请求的机器上正确设置日期时间,否则您将获得403.

答案 2 :(得分:0)

我看起来像IAM政策问题。 您的本地计算机上的用户策略与您的IAM角色策略有什么关系? 对于您的EC2实例,在创建它时,使用“AmazonS3FullAccess”策略创建一个角色,如果它解决了问题,您将删除无用的权限。

答案 3 :(得分:0)

您需要为存储桶执行操作“ ListBucket”,而不需要为存储桶中的文件执行以下操作:        {             “动作”:[                 “ s3:ListBucket”             ],             “ Resource”:“ arn:aws:s3 ::: bucketName”,             “效果”:“允许”         }