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

如何使用AWS SDK v2实现跨AWS账号的S3对象复制?

跨AWS账号S3对象复制403错误解决方案

跨账号复制报403的核心原因是双端权限配置不全,按照以下步骤处理即可:

1. 源账号侧配置(源存储桶所属账号A)

在源存储桶的资源策略中添加配置,给目标账号(账号B)开放源存储桶和对象的读权限,替换配置中的占位符即可:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::目标账号B的12位账号ID:root"
            },
            "Action": [
                "s3:GetObject",
                "s3:GetObjectAcl",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::源存储桶名称",
                "arn:aws:s3:::源存储桶名称/*"
            ]
        }
    ]
}

如果源存储桶开启了KMS加密,还需要在对应KMS密钥的策略中给账号B开放kms:Decrypt权限

2. 目标账号侧配置(目标存储桶所属账号B,即代码中AK/SK所属账号)

给代码使用的AK/SK对应的IAM身份(用户/角色)配置如下权限策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::目标存储桶名称",
                "arn:aws:s3:::目标存储桶名称/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectAcl"
            ],
            "Resource": "arn:aws:s3:::源存储桶名称/*"
        }
    ]
}

如果目标存储桶开启了KMS加密,需要额外给对应IAM身份加kms:GenerateDataKey权限

3. 代码适配调整

你当前代码中手动对copySource做URL编码属于多余操作,AWS SDK v2会自动处理编码逻辑,手动编码反而可能在对象名含特殊字符时触发错误,调整后代码如下:

public void copyObjects(S3Object[] s3DestObjects, String sDestBucket, String sSourceBucket, String sSourceObject) {
    try {
        AwsBasicCredentials awsCreds = AwsBasicCredentials.create(
                ACCESS_KEY,
                SECRET_KEY);
        S3Client s3Client = S3Client.builder()
                .credentialsProvider(StaticCredentialsProvider.create(awsCreds))
                .region(Region.US_EAST_2)
                .build();
        // 移除手动编码逻辑,直接拼接源桶+源对象路径
        String copySource = sSourceBucket + "/" + sSourceObject;
        for (S3Object s3DestObject : s3DestObjects) {
            CopyObjectRequest copyObjectRequest = CopyObjectRequest.builder()
                    .copySource(copySource)
                    .destinationBucket(sDestBucket)
                    .destinationKey(s3DestObject.key)
                    .metadata(s3DestObject.getMetadata())
                    .metadataDirective(MetadataDirective.REPLACE)
                    // 如果目标存储桶开启了桶拥有者强制接管,需加以下配置确保对象归属权转移
                    // .acl(ObjectCannedACL.BUCKET_OWNER_FULL_CONTROL)
                    .build();
            CopyObjectResponse copyObjectResponse = s3Client.copyObject(copyObjectRequest);
        }
    } catch (S3Exception e) {
        throw e;
    }
}

4. 异常排查补充

如果配置后仍报错,可按以下方向校验:

  • 确认源存储桶的区域和代码中配置的区域匹配,如果源桶不在us-east-2,需要在复制请求中单独指定源区域参数
  • 确认源对象未开启对象锁、合规保留等限制访问的配置
  • 确认使用的AK/SK没有附加权限边界、会话策略等额外权限限制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 16:09:00