尽管 IAM 角色和区域正确,但在部署的 Elastic Beanstalk Java 应用程序中 S3 访问失败

问题描述 投票:0回答:1

我想从 Java Elastic Beanstalk 应用程序访问 AWS S3 存储桶中的文件。

应用程序(Spring Boot 微服务)在本地运行时运行良好。列出、读取和写入存储桶中的对象没有问题。

这就是我构建 S3 客户端的方式:

AmazonS3 s3client = AmazonS3ClientBuilder 
.standard() 
.withRegion(Regions.EU_WEST_2) 
.build();

这就是我列出存储桶中对象的方式:

s3client.listObjects(<BUCKET_NAME>).getObjectSummaries();

在 IAM 中我创建了一个具有权限的角色:

  • AmazonS3FullAccess
  • AWSElasticBeanstalkEnhancedHealth
  • AWSElasticBeanstalkManagedUpdatesCustomerRolePolicy
  • AWSElasticBeanstalk多容器Docker
  • AWSElasticBeanstalkWebTier

在 Elastic Beanstalk 环境中,我已将其设置为服务角色和 EC2 实例配置文件。

但是,当我部署应用程序时,对存储桶的访问失败:

com.amazonaws.services.s3.model.AmazonS3Exception:存储桶位于 该区域:eu-central-1。请使用该区域重试请求 (服务:Amazon S3;状态代码:301;

此错误消息不正确。根据bucket概览,该bucket位于AWS Region 欧洲(伦敦)eu-west-2

我已尝试遵循建议并使用它建议的区域:

AmazonS3 s3client = AmazonS3ClientBuilder 
.standard() 
.withRegion(Regions.EU_CENTRAL_1) 
.build();

然后返回拒绝访问错误消息:

由以下原因引起:com.amazonaws.services.s3.model.AmazonS3Exception:访问 被拒绝(服务:Amazon S3;状态代码:403;错误代码: 访问被拒绝;

Elastic Beanstalk 应用程序的域显示它正在与其尝试访问的 S3 存储桶在同一区域中运行:

.eu-west-2.elasticbeanstalk.com

为了清楚起见,该存储桶是我通过 AWS S3 控制台使用我的帐户创建的。我的帐户是该存储桶的所有者。该应用程序也是我通过 Elastic Beanstalk 控制台使用我的帐户创建的。我还有其他 Java Elastic Beanstalk 应用程序,部署后可以毫无问题地访问 S3 存储桶,这意味着不存在帐户范围内的原因。

我还尝试了以下操作,这也会导致访问被拒绝错误响应。

AmazonS3 s3client = AmazonS3ClientBuilder 
.standard() 
.enableForceGlobalBucketAccess()
.build();

如何让该应用程序在部署后访问 S3?

java amazon-s3 amazon-elastic-beanstalk
1个回答
0
投票

事实证明,由于缺少环境变量导致使用默认存储桶名称,我没有访问我认为的存储桶。不幸的是,默认存储桶名称实际上是由不同区域的不同 AWS 账户注册的真实存储桶。因此,AWS 错误消息是正确的,但如果错误消息包含拒绝访问的存储桶的名称,问题会更加明显。

环境变量是在本地定义的,因此不会影响我的本地开发计算机 - 只有部署的实例受到影响。请务必在调用 SDK 之前打印存储桶名称,以确保拒绝访问的“资源”符合预期。

© www.soinside.com 2019 - 2024. All rights reserved.