You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置S3存储桶:仅允许指定IAM角色执行上传操作

排查S3桶上传权限限制失效的问题

我之前也踩过类似的权限配置坑,咱们一步步拆解来看,应该能快速找到根源:

1. 桶策略的Resource范围不完整(最常见原因)

你当前的桶策略里,Resource只写了桶的ARN arn:aws:s3:::MyExampleBucket,但s3:PutObject是对象级操作,对应的Resource需要包含桶内所有对象的路径(也就是arn:aws:s3:::MyExampleBucket/*)。原策略只限制了桶级别的操作(比如创建桶、删除桶),完全没覆盖对象上传这类核心操作,所以权限限制自然不生效。

修改后的桶策略应该把Resource改成数组,同时包含桶和对象路径:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::MyExampleBucket",
        "arn:aws:s3:::MyExampleBucket/*"
      ],
      "Condition": {
        "StringNotLike": {
          "aws:userId": [
            "AROAEXAMPLEID:*",
            "111111111111"
          ]
        }
      }
    }
  ]
}

2. 确认当前调用身份的aws:userId是否匹配策略

策略里只允许AROAEXAMPLEID:*(角色ID前缀)和账号ID111111111111的身份操作桶,你需要确认Java SDK使用的凭证对应的userId是否在这个范围内:

可以在代码里加一段STS调用,直接获取当前身份的信息:

import com.amazonaws.services.securitytoken.AmazonSTS;
import com.amazonaws.services.securitytoken.AmazonSTSClientBuilder;
import com.amazonaws.services.securitytoken.model.GetCallerIdentityResult;

public class CheckCallerIdentity {
    public static void main(String[] args) {
        AmazonSTS stsClient = AmazonSTSClientBuilder.defaultClient();
        GetCallerIdentityResult result = stsClient.getCallerIdentity();
        System.out.println("当前身份的User ID: " + result.getUserId());
        System.out.println("所属账号ID: " + result.getAccount());
    }
}
  • 如果是使用IAM角色的临时凭证,userId格式是AROAEXAMPLEID:会话名称,会匹配AROAEXAMPLEID:*;
  • 如果是用IAM用户的永久凭证,userId是AIDAxxxxxx开头的,不在策略允许范围内,会被拒绝(如果这不是你想要的,需要把用户ID加入策略)。

3. 确认Java SDK使用的是目标角色的凭证

如果你的目标是只允许特定IAM角色上传,要确保s3Client确实使用了该角色的临时凭证,而不是其他用户/角色的凭证。比如通过AssumeRole获取角色凭证的代码示例:

import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.securitytoken.AWSSecurityTokenService;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
import com.amazonaws.services.securitytoken.model.AssumeRoleResult;

public class S3UploadWithRole {
    public static void main(String[] args) {
        // 1. 调用STS获取目标角色的临时凭证
        AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard().build();
        AssumeRoleRequest roleRequest = new AssumeRoleRequest()
                .withRoleArn("arn:aws:iam::111111111111:role/你的目标角色名")
                .withRoleSessionName("s3-upload-session");
        AssumeRoleResult roleResponse = stsClient.assumeRole(roleRequest);

        // 2. 用临时凭证创建S3客户端
        BasicSessionCredentials sessionCredentials = new BasicSessionCredentials(
                roleResponse.getCredentials().getAccessKeyId(),
                roleResponse.getCredentials().getSecretAccessKey(),
                roleResponse.getCredentials().getSessionToken());

        AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(sessionCredentials))
                .build();

        // 3. 执行上传操作
        // s3Client.putObject(request);
    }
}

4. 排查其他权限冲突

IAM权限遵循Deny优先于Allow的原则,但如果有其他策略(比如IAM角色/用户的内联策略、托管策略)允许了s3:PutObject,但你的桶策略因为Resource范围问题没覆盖到对象操作,那还是会允许上传。所以确保修改桶策略后,所有不符合条件的请求都会被Deny。

按照上面的步骤排查和调整,应该就能实现你想要的上传权限限制了。

内容的提问来源于stack exchange,提问作者sdc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:35:46