使用 IAM 凭证和策略 Java AWS SDK 将文件上传到 S3 存储桶

Upload file to S3 bucket using IAM credentials and policy Java AWS SDK

我正在尝试将文件上传到 S3 存储桶。首先,我使用 InstanceProfileCredentialsProvider 创建一个 AmazonS3 客户端,并从实例元数据中获取 IAM 凭证:

final AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
    .withCredentials(new InstanceProfileCredentialsProvider(false))
    .withRegion("eu-west-1").build();

与此实例关联的角色具有访问文件并将文件上传到存储桶的策略:

{  
    "Version":"2012-10-17",
       "Statement":{  
  "Action":[  
     "kms:Decrypt",
     "kms:DescribeKey",
     "kms:Encrypt",
     "kms:GenerateDataKey",
     "kms:ReEncryptFrom",
     "kms:ReEncryptTo",
     "s3:GetObject",
     "s3:ListBucket",
     "s3:PutObject*"
  ],
          "Effect":"Allow",
          "Resource":[  
          "arn:aws:kms:eu-west-1:[account-id]:key/[key-id]",
          "arn:aws:s3:::[bucket-name]",
          "arn:aws:s3:::[bucket-name]/[path-were-to-save-file]/*" 

  ]}}

我正在尝试像这样上传文件:

final PutObjectRequest request = new PutObjectRequest("[bucket-name]", file.getName(), file);

s3Client.putObject(request);

但我收到拒绝访问 AmazonS3ClientException。知道我错过了什么吗?

我还尝试在请求中包含 kms 密钥:

final PutObjectRequest request = new PutObjectRequest("[bucket-name]", file.getName(), file)
                .withSSEAwsKeyManagementParams(new SSEAwsKeyManagementParams("[key-id]"));

但它试图从我的帐户中检索密钥:

arn:aws:kms:eu-west-1:[my-account-id]:key/[key-id]

不是策略中指定的帐户:

arn:aws:kms:eu-west-1:[account-id]:key/[key-id]

并抛出 KMSNotFoundException

似乎我必须指定完整路径才能保存文件并且我可以丢弃密钥:

final PutObjectRequest request = new PutObjectRequest("[bucket-name]", "[path-were-to-save-file]/" + file.getName(), file);

如果需要传递密钥,则不仅需要提供密钥 ID,还需要提供完整的 arn:

final PutObjectRequest request = new PutObjectRequest("[bucket-name]", file.getName(), file)
    .withSSEAwsKeyManagementParams(new SSEAwsKeyManagementParams("arn:aws:kms:eu-west-1:[account-id]:key/[key-id]"));