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

2023年10月如何用AWS Java SDK 1.12.x开启S3 Bucket公共读取权限?

如何通过Java代码实现S3桶公共读取权限(AWS 2023年4月规则变更后)

2023年4月AWS S3规则更新后,ACL方式的公共权限不再生效,必须先禁用桶的Public Access Block,再配置公共读取桶策略。目前手动在控制台关闭“阻止所有公共访问”后,网页可以正常读取index.html,但需要动态创建桶,无法逐个手动操作。代码中设置桶策略成功,但调用setPublicAccessBlock时提示Access Denied,求解决方法。

用户提供的代码如下:

public S3_UpdaterController()
{
    
    s3client.createBucket("ecotest123456789");
    List buckets = s3client.listBuckets();
    
    for (Object object : buckets) {
        System.out.println(object.toString());
    }
    
    String bucketname = "ecotest123456789";
    
    String initialString = "<html>test</html>";
    java.io.InputStream targetStream = new java.io.ByteArrayInputStream(initialString.getBytes());
    
    PutObjectRequest putObjectRequest = new PutObjectRequest("ecotest123456789", "index.html", targetStream,null);
    //s3client.deleteBucketPolicy(bucketname);
   
    
    s3client.setBucketPolicy(bucketname, getPublicReadPolicy(bucketname));
    
    BucketPolicy bucket_policy = s3client.getBucketPolicy(bucketname);
    
    System.out.println(bucket_policy.getPolicyText());
    
    AccessControlList acl = new AccessControlList();
    acl.grantPermission(GroupGrantee.AllUsers, Permission.Read); //all users or authenticated
    //putObjectRequest.setAccessControlList(acl);
    
    s3client.putObject(putObjectRequest);//.withCannedAcl(CannedAccessControlList.PublicRead));
    s3client.setBucketWebsiteConfiguration(bucketname,new BucketWebsiteConfiguration("index.html"));
    
    //THIS ONE FAILS WITH ACCESS DENIED
    s3client.setPublicAccessBlock(new SetPublicAccessBlockRequest().withBucketName(bucketname));
    
    
}

public static String getPublicReadPolicy(String bucket_name) {
    Policy bucket_policy = new Policy().withStatements(
            new Statement(Statement.Effect.Allow)
                    .withPrincipals(Principal.AllUsers)
                    .withActions(S3Actions.GetObject)
                    .withResources(new Resource(
                            "arn:aws:s3:::" + bucket_name + "/*")));
    return bucket_policy.toJson();
}

解决步骤

1. 确保IAM权限足够

调用setPublicAccessBlock需要IAM实体(用户/角色)拥有s3:PutPublicAccessBlock权限,同时检查是否存在组织级S3公共访问阻止策略限制——如果组织强制开启了公共访问阻止,即使IAM有权限也无法修改,需要联系管理员调整组织策略。

2. 修正setPublicAccessBlock的代码参数

当前代码仅指定了桶名,没有设置具体的公共访问阻止配置,默认不会关闭所有限制。需要明确设置四个参数为false,以完全禁用Public Access Block:

// 替换原有的setPublicAccessBlock调用
PublicAccessBlockConfiguration config = new PublicAccessBlockConfiguration()
    .withBlockPublicAcls(false)
    .withIgnorePublicAcls(false)
    .withBlockPublicPolicy(false)
    .withRestrictPublicBuckets(false);

SetPublicAccessBlockRequest request = new SetPublicAccessBlockRequest()
    .withBucketName(bucketname)
    .withPublicAccessBlockConfiguration(config);

s3client.setPublicAccessBlock(request);

3. 调整操作顺序

正确的流程应该是:创建桶 → 禁用Public Access Block → 设置桶策略 → 上传对象 → 配置网站。因为如果Public Access Block开启,后续的桶策略可能无法生效。调整后的代码顺序参考:

public S3_UpdaterController()
{
    String bucketname = "ecotest123456789";
    // 1. 创建桶
    s3client.createBucket(bucketname);
    
    // 2. 禁用Public Access Block(修正后的代码)
    PublicAccessBlockConfiguration config = new PublicAccessBlockConfiguration()
        .withBlockPublicAcls(false)
        .withIgnorePublicAcls(false)
        .withBlockPublicPolicy(false)
        .withRestrictPublicBuckets(false);
    SetPublicAccessBlockRequest request = new SetPublicAccessBlockRequest()
        .withBucketName(bucketname)
        .withPublicAccessBlockConfiguration(config);
    s3client.setPublicAccessBlock(request);
    
    // 3. 设置公共读取桶策略
    s3client.setBucketPolicy(bucketname, getPublicReadPolicy(bucketname));
    
    // 4. 上传对象(可选:设置对象的公共读取权限,配合桶策略)
    String initialString = "<html>test</html>";
    java.io.InputStream targetStream = new java.io.ByteArrayInputStream(initialString.getBytes());
    PutObjectRequest putObjectRequest = new PutObjectRequest(bucketname, "index.html", targetStream,null)
        .withCannedAcl(CannedAccessControlList.PublicRead); // 可选,增强兼容性
    s3client.putObject(putObjectRequest);
    
    // 5. 配置静态网站
    s3client.setBucketWebsiteConfiguration(bucketname,new BucketWebsiteConfiguration("index.html"));
    
    // 验证桶列表
    List buckets = s3client.listBuckets();
    for (Object object : buckets) {
        System.out.println(object.toString());
    }
}

4. 验证桶策略和访问权限

设置完成后,可通过AWS控制台检查桶的Public Access Block状态是否为“关闭所有公共访问阻止”,同时确认桶策略已正确应用。访问网站端点验证index.html是否可正常访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 01:48:31