设置Bucket ACL

重要

本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。

当您希望粗粒度地控制某个Bucket的读写权限,即Bucket内的所有Object均为统一的读写权限时,您可以选择使用Bucket ACL的方式。Bucket ACL包含公共读、公共读写和私有。您可以在创建Bucket时设置Bucket ACL,也可以在创建Bucket后根据自身的业务需求修改Bucket ACL。

注意事项

  • Bucket拥有者可以执行修改Bucket ACL的操作。

  • 修改Bucket ACL会影响Bucket内所有ACL为继承Bucket的文件。

  • 如果您在上传文件(Object)时未指定文件的ACL,则文件的ACL默认继承Bucket ACL。

读写权限类型

Bucket包含以下三种读写权限:

权限值

权限描述

public-read-write

公共读写:任何人(包括匿名访问者)都可以对该Bucket内文件进行读写操作。

警告

互联网上任何用户都可以对该Bucket内的文件进行访问,并且向该Bucket写入数据。这有可能造成您数据的外泄以及费用激增,如果被人恶意写入违法信息还可能会侵害您的合法权益。除特殊场景外,不建议您配置公共读写权限。

public-read

公共读:只有该Bucket的拥有者可以对该Bucket内的文件进行写操作,任何人(包括匿名访问者)都可以对该Bucket中的文件进行读操作。

警告

互联网上任何用户都可以对该Bucket内文件进行访问,这有可能造成您数据的外泄以及费用激增,请谨慎操作。

private(默认值)

私有:只有Bucket的拥有者可以对该Bucket内的文件进行读写操作,其他人无法访问该Bucket内的文件。

操作方式

使用OSS控制台

  1. 登录OSS管理控制台

  2. 单击Bucket 列表,然后单击目标Bucket名称。

  3. 在左侧导航栏,选择权限控制 > 读写权限

  4. 读写权限页签,单击设置,按实际需求修改Bucket ACL。

  5. 单击保存

使用图形化管理工具ossbrowser

ossbrowser支持Bucket级别的操作与控制台支持的操作类似,请按照ossbrowser界面指引完成修改Bucket ACL的操作。关于使用ossbrowser的具体操作,请参见常用操作

使用阿里云SDK

以下仅列举常见SDK的修改存储空间ACL的代码示例。关于其他SDK的修改存储空间ACL代码示例,请参见SDK简介

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.CannedAccessControlList;

public class Demo {
    public static void main(String[] args) throws Exception {
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "examplebucket";
        // 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。
        String region = "cn-hangzhou";

        // 创建OSSClient实例。
        // 当OSSClient实例不再使用时,调用shutdown方法以释放资源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();

        try {
            // 设置存储空间的读写权限。例如将examplebucket的读写权限ACL设置为私有Private。
            ossClient.setBucketAcl(bucketName, CannedAccessControlList.Private);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}
const OSS = require('ali-oss');

const client = new OSS({
  // region以杭州为例(oss-cn-hangzhou),其他region按实际情况填写。
  region: '<Your region>',
  // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
  // 填写存储空间名称。
  bucket: 'yourBucketName',
});


async function putBucketACL() {
// 设置存储空间的读写权限为私有。
  const acl = 'private'
  try {
    await client.putBucketACL('<Your Bucket Name>', acl)
  } catch (error) {
    console.log(error)
  }
}

putBucketACL()
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* 初始化OSS账号信息。*/
            
    /* yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。*/
    std::string Endpoint = "yourEndpoint";
    / *yourRegion填写Bucket所在地域对应的Region。以华东1(杭州)为例,Region填写为cn - hangzhou。 * /
    std::string Region = "yourRegion";
    /* 填写Bucket名称,例如examplebucket。*/
    std::string BucketName = "examplebucket";

    /* 初始化网络等资源。*/
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    /* 设置存储空间访问权限为私有。*/
    SetBucketAclRequest request(BucketName, CannedAccessControlList::Private);
    auto outcome = client.SetBucketAcl(request);

    if (outcome.isSuccess()) {    
        std::cout << " setBucketAcl successfully " << std::endl;
    }
    else {
        /* 异常处理。*/
        std::cout << "SetBucketAcl fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

    /* 释放网络等资源。*/
    ShutdownSdk();
    return 0;
}
#include "oss_api.h"
#include "aos_http_io.h"
/* yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。*/
const char *endpoint = "yourEndpoint";

/* 填写Bucket名称,例如examplebucket。*/
const char *bucket_name = "examplebucket";
/* yourRegion填写Bucket所在地域对应的Region。以华东1(杭州)为例,Region填写为cn-hangzhou。*/
const char *region = "yourRegion";
void init_options(oss_request_options_t *options)
{

    options->config = oss_config_create(options->pool);
    /* 用char*类型的字符串初始化aos_string_t类型。*/
    aos_str_set(&options->config->endpoint, endpoint);
    /* 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/    
    aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID"));
    aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET"));
    //需要额外配置以下两个参数
    aos_str_set(&options->config->region, region);
    options->config->signature_version = 4;
    /* 是否使用CNAME域名访问OSS服务。0表示不使用。*/
    options->config->is_cname = 0;
    /* 设置网络相关参数,比如超时时间等。*/
    options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
    /* 在程序入口调用aos_http_io_initialize方法来初始化网络、内存等全局资源。*/
    if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
        exit(1);
    }
    /* 用于内存管理的内存池(pool),等价于apr_pool_t。其实现代码在apr库中。*/
    aos_pool_t *pool;
    /* 重新创建一个内存池,第二个参数是NULL,表示没有继承其它内存池。*/
    aos_pool_create(&pool, NULL);
    /* 创建并初始化options,该参数包括endpoint、access_key_id、acces_key_secret、is_cname、curl等全局配置信息。*/
    oss_request_options_t *oss_client_options;
    /* 在内存池中分配内存给options。*/
    oss_client_options = oss_request_options_create(pool);
    /* 初始化Client的选项oss_client_options。*/
    init_options(oss_client_options);
    /* 初始化参数。*/
    aos_string_t bucket;
    aos_table_t *resp_headers = NULL; 
    aos_status_t *resp_status = NULL; 
    /* 将char*类型数据赋值给aos_string_t类型的存储空间。*/
    aos_str_set(&bucket, bucket_name);
    /* 设置存储空间权限为公共读(OSS_ACL_PUBLIC_READ)。*/
    resp_status = oss_put_bucket_acl(oss_client_options, &bucket, OSS_ACL_PUBLIC_READ, &resp_headers);
    if (aos_status_is_ok(resp_status)) {
        printf("set bucket acl succeeded\n");
    } else {
        printf("set bucket acl failed\n");
    }
    /* 释放内存池,相当于释放了请求过程中各资源分配的内存。*/
    aos_pool_destroy(pool);
    /* 释放之前分配的全局资源。*/
    aos_http_io_deinitialize();
    return 0;
}
require 'aliyun/oss'

client = Aliyun::OSS::Client.new(
  # Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
  endpoint: 'https://oss-cn-hangzhou.aliyuncs.com',
  # 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  access_key_id: ENV['OSS_ACCESS_KEY_ID'],
  access_key_secret: ENV['OSS_ACCESS_KEY_SECRET']
)
# 填写Bucket名称,例如examplebucket。
bucket = client.get_bucket('examplebucket')
bucket.acl = Aliyun::OSS::ACL::PUBLIC_READ
puts bucket.acl
package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// 定义全局变量
var (
	region     string // 存储区域
	bucketName string // 存储空间名称
)

// init函数用于初始化命令行参数
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
}

func main() {
	// 解析命令行参数
	flag.Parse()

	// 检查bucket名称是否为空
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// 检查region是否为空
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// 加载默认配置并设置凭证提供者和区域
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// 创建OSS客户端
	client := oss.NewClient(cfg)

	// 创建设置存储空间ACL的请求
	putRequest := &oss.PutBucketAclRequest{
		Bucket: oss.Ptr(bucketName),  // 存储空间名称
		Acl:    oss.BucketACLPrivate, // 设置为私有访问权限
	}

	// 执行设置存储空间ACL的操作
	putResult, err := client.PutBucketAcl(context.TODO(), putRequest)
	if err != nil {
		log.Fatalf("failed to put bucket acl %v", err)
	}

	// 打印设置存储空间ACL的结果
	log.Printf("put bucket acl result: %#v\n", putResult)

	// 创建获取存储空间ACL的请求
	getRequest := &oss.GetBucketAclRequest{
		Bucket: oss.Ptr(bucketName), // 存储空间名称
	}

	// 执行获取存储空间ACL的操作
	getResult, err := client.GetBucketAcl(context.TODO(), getRequest)
	if err != nil {
		log.Fatalf("failed to get bucket acl %v", err)
	}

	// 打印获取存储空间ACL的结果
	log.Printf("get bucket acl result:%#v\n", getResult)
}
import argparse
import alibabacloud_oss_v2 as oss

# 创建一个命令行参数解析器,并添加描述信息
parser = argparse.ArgumentParser(description="put bucket acl sample")
# 添加必需的命令行参数:region(区域)、bucket(存储空间名称)和acl(访问控制列表)
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# 添加可选的命令行参数:endpoint,用于指定其他服务访问OSS时使用的域名
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# 添加必需的命令行参数:acl(访问控制列表),用于指定存储空间的访问权限,例如 private、public-read、public-read-write
parser.add_argument('--acl', help='Specify the access permission ACL for the bucket.', required=True)

def main():
    # 解析命令行参数
    args = parser.parse_args()

    # 从环境变量中加载认证信息
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 使用SDK默认配置
    cfg = oss.config.load_default()
    # 设置认证提供者
    cfg.credentials_provider = credentials_provider
    # 设置区域
    cfg.region = args.region
    # 如果提供了endpoint,则更新endpoint到配置中
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 创建OSS客户端
    client = oss.Client(cfg)

    # 调用put_bucket_acl方法设置存储空间的ACL
    result = client.put_bucket_acl(oss.PutBucketAclRequest(
        bucket=args.bucket,
        acl=args.acl,
    ))

    # 打印请求的状态码和请求ID
    print(f'status code: {result.status_code}, request id: {result.request_id}')

    # 获取指定存储空间的ACL(访问控制列表)
    result = client.get_bucket_acl(oss.GetBucketAclRequest(
        bucket=args.bucket,
    ))

    # 打印结果中的状态码、请求ID和ACL信息
    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' acl: {result.acl},'
    )

if __name__ == "__main__":
    main()
<?php

// 引入自动加载文件 加载依赖库
require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// 定义命令行参数描述
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located', 'required' => True], // 区域是必填项 存储空间所在的区域
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS', 'required' => False], // 终端节点是可选项 其他服务可以用来访问OSS的域名
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // 存储空间名称是必填项
];

// 生成长选项列表 用于解析命令行参数
$longopts = \array_map(function ($key) {
    return "$key:"; // 每个参数后面加冒号 表示需要值
}, array_keys($optsdesc));

// 解析命令行参数
$options = getopt("", $longopts); 

// 检查必填参数是否缺失
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help'];
        echo "Error: the following arguments are required: --$key, $help"; // 提示用户缺少必填参数
        exit(1); 
    }
}

// 获取命令行参数值
$region = $options["region"]; // 存储空间所在区域
$bucket = $options["bucket"]; // 存储空间名称

// 使用环境变量加载凭证信息 AccessKeyId 和 AccessKeySecret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

// 使用SDK的默认配置
$cfg = Oss\Config::loadDefault();

// 设置凭证提供者
$cfg->setCredentialsProvider($credentialsProvider);

// 设置区域
$cfg->setRegion($region);

// 如果提供了终端节点 则设置终端节点
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]);
}

// 创建OSS客户端实例
$client = new Oss\Client($cfg);

// 创建设置存储空间ACL的请求对象 将ACL设置为私有
$request = new Oss\Models\PutBucketAclRequest(
      bucket: $bucket, 
      acl: Oss\Models\BucketACLType::PRIVATE);

// 调用putBucketAcl方法设置存储空间的ACL
$result = $client->putBucketAcl($request);

// 打印返回结果
printf(
    'status code:' . $result->statusCode . PHP_EOL . // HTTP响应状态码
    'request id:' . $result->requestId // 请求的唯一标识
);

使用命令行工具ossutil

您可以使用命令行工具ossutil来配置Bucket ACL,ossutil的安装请参见安装ossutil

以下命令用于将存储空间examplebucket的访问权限设置为私有。

ossutil api put-bucket-acl --bucket examplebucket --acl private

关于该命令的更多信息,请参见put-bucket-acl

相关API

以上操作方式底层基于API实现,如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。更多信息,请参见PutBucketAcl

常见问题

CDN回源OSS时,OSSBucket ACL是否必须为公共读或者公共读写?

不需要。在Bucket ACL为私有时,您可以开启CDN回源私有Bucket。具体操作,请参见OSS私有Bucket回源

相关文档

  • 如果您希望长期授予其他用户细粒度的权限,例如拥有Bucket下指定前缀的文件只读或者只写的权限,您需要选择Bucket Policy或者RAM Policy的方式。更多信息,请参见Bucket Policy常见示例RAM Policy常见示例

  • 如果您希望临时授予其他用户细粒度的权限,例如拥有列举某个Bucket下所有文件的权限,您需要选择STS临时授权的方式。更多信息,请参见使用STS临时访问凭证访问OSS