我在AWS中有一个S3 Bucket设置,由IAM角色保护。我正在编写一个应用程序,该应用程序应该访问该bucket。应用程序部署到EKS集群,并通过服务帐户设置(遵循IRSA概念(获得角色。到目前为止,这还可以。
但对于测试/开发,我希望能够在本地运行应用程序。那么,在本地运行时,如何将IAM角色分配给我的应用程序呢?
当在EKS中运行时,权限由集群处理,因此从Java代码中,我只需要创建一个默认的S3客户端,然后我就可以放置对象:
AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient();
s3Client.putObject(bucketName, key, data);
这当然不会在本地开箱即用。
我的配置文件中定义了一个AWS配置文件:
[profile test]
role_arn = arn:aws:iam::...
source_profile = default
region = eu-central-1
### MFA Authenticated
[default]
region = eu-central-1
当登录时,我可以使用从控制台看到bucket
aws s3api list-objects --bucket <bucketname> --profile test
我通过提供环境变量将我的配置文件连接到应用程序:
AWS_PROFILE=test
AWS_REGION=eu-central-1
我也试过AWS_PROFILE="profile test"
。
当运行我的代码时,我得到
com.amazonaws.services.s3.model.AmazonS3Exception:
Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4.
(Service: Amazon S3; Status Code: 400; Error Code: InvalidArgument;
我使用的是Java SDK 1.11.738,并在maven的pom.xml中确保SDK-s3、SDK-core和SDK-kms都有相同的版本:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.11.738</version>
<exclusions>
<exclusion>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-kms</artifactId>
</exclusion>
<exclusion>
<groupId>com.amazonaws</groupId>
<artifactId>jmespath-java</artifactId>
</exclusion>
</exclusions> </dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-core</artifactId>
<version>1.11.738</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-kms</artifactId>
<version>1.11.738</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>jmespath-java</artifactId>
<version>1.11.738</version>
</dependency>
在我看来,您有不同的问题。
您收到的错误是由于您没有指定签名版本。
System.setProperty(SDKGlobalConfiguration.ENABLE_S3_SIGV4_SYSTEM_PROPERTY, "true");
进一步阅读。
其次,对于角色,需要在EKS实例上设置该角色。
您需要使用arn获取以下的临时值。
ACCESS_ KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_SESSION_TOKEN
然后将它们添加到服务的环境变量中,或者在本地启动服务时将它们作为环境变量传递。