通过资源组授予多个Bucket相同权限

更新时间:2025-04-18 02:26:25

资源组是一种基于资源的权限管理方式。您可以将需要授予同样权限的Bucket归为同一个资源组,然后统一为该资源组授权,从而提升授权效率。

背景信息

企业用户采用为每个项目创建云账号的方式来隔离资源,或者企业的不同子公司或部门为实现业务上云时创建了不同的云账号,导致一家企业拥有大量的云账号,最终无法统一管理、监控和审计云上资源。

account

为解决以上业务痛点,OSS支持用户通过单个阿里云账号,根据不同使用场景以资源组的方式对不同云资源进行合理分类,赋予企业内不同项目成员按项目自治管理云资源的能力。

rg

注意事项

  • 一个资源组可以包含不同地域的Bucket。一个Bucket只能属于一个资源组。

  • 仅允许在Bucket拥有者名下不同资源组之间转移Bucket。

操作方式

使用OSS控制台

假设某互联网公司使用了20Bucket存储不同部门的测试数据。要求examplebucket1~examplebucket10的数据所有员工可读(公共读),examplebucket11~examplebucket20的数据所有员工可读可写(公共读写)。如果不使用资源组,您需要分别对每个Bucket进行授权,非常繁琐。如果使用了资源组,您可以将需要授予同样权限的Bucket归为一组,然后统一为该资源组授权,从而极大提升授权效率。

此外,考虑到要为多名员工赋予相同权限,您需要创建用户组并对RAM用户进行分类和授权,从而更好的管理用户及其权限。

  1. 创建用户组UserGroup1并添加用户组成员。

    通过RAM控制台创建用户组时,用户组名称命名为UserGroup1。具体操作,请参见创建RAM用户组。用户组创建完成后,将所有需要访问资源的用户添加到用户组。具体操作,请参见RAM用户组添加RAM用户

  2. 创建资源组。

    1. 打开资源管理控制台

    2. 在左侧导航栏,选择资源组>资源组

    3. 资源组页面,单击创建资源组

    4. 创建资源组面板,填写资源组名称ResourcegroupA,并自定义资源组标识,例如Group1

    5. 单击确认

      此时,资源组的状态处于创建中。大约三秒后,单击资源组_刷新列表。如果状态变为可用,表示资源组ResourcegroupA创建成功。

    6. 重复上述步骤创建ResourcegroupB。

  3. 为目标Bucket选择所属资源组。

    1. 登录OSS管理控制台

    2. 单击Bucket 列表,然后单击目标存储空间examplebucket1。

    3. 选择Bucket 配置 > 资源组

    4. 资源组页面,单击设置

    5. 选择所属资源组ResourcegroupA,然后单击保存

    6. 重复上述步骤为examplebucket2~examplebucket10选择所属资源组ResourcegroupA,为examplebucket11~examplebucket20选择所属资源组ResourcegroupB。

  4. 为资源组授权。

    1. 在资源管理控制台的左侧导航栏,选择资源组>资源组。

    2. 单击目标资源组右侧的权限管理

    3. 权限管理页签,单击新增授权

    4. 新增授权面板,按如下说明完成各配置项。

      配置项

      说明

      授权范围

      选中指定资源组,并从下拉列表中选择ResourcegroupA。

      授权主体

      填写已创建的用户组UserGroup1。

      选择权限

      选中系统策略后,为资源组ResourcegroupA授予只读访问对象存储服务(OSS)的权限AliyunOSSReadOnlyAccess

    5. 单击确定

    6. 单击完成

    7. 重复上述步骤为资源组ResourcegroupB授予管理对象存储服务(OSS)权限AliyunOSSFullAccess

使用阿里云SDK

Java SDK、Python SDKGo SDK支持配置Bucket所属资源组。请参见SDK简介

Java
Go
Python
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.model.SetBucketResourceGroupRequest;

public class Demo {
    public static void main(String[] args) throws Throwable {
        // 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";
        // 填写资源组ID。如果未填写资源组ID,则Bucket归属于默认资源组。
        String rgId = "rg-aekz****";
        // 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。
        String region = "cn-hangzhou";
        
        // 创建OSSClient实例。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();

        try {
            // 创建setBucketResourceGroupRequest对象。
            SetBucketResourceGroupRequest setBucketResourceGroupRequest = new SetBucketResourceGroupRequest(bucketName,rgId);
            // 配置Bucket所属资源组。
            ossClient.setBucketResourceGroup(setBucketResourceGroupRequest);
        } 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();
            }
        }
    }
}
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()

	// 填写资源组ID。如果未填写资源组ID,则bucket归属于默认资源组
	var groupId string = "rg-aekz****"

	// 检查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)

	// 创建设置存储空间资源组的请求
	request := &oss.PutBucketResourceGroupRequest{
		Bucket: oss.Ptr(bucketName), // 存储空间名称
		BucketResourceGroupConfiguration: &oss.BucketResourceGroupConfiguration{
			ResourceGroupId: oss.Ptr(groupId),
		},
	}

	// 发送设置存储空间资源组的请求
	result, err := client.PutBucketResourceGroup(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to put bucket resource group %v", err)
	}

	// 打印设置存储空间资源组的结果
	log.Printf("put bucket resource group result:%#v\n", result)
}
import argparse
import alibabacloud_oss_v2 as oss

# 创建命令行参数解析器,并描述脚本用途:设置存储空间(Bucket)的资源组配置
parser = argparse.ArgumentParser(description="put bucket resource group sample")

# 定义命令行参数,包括必需的区域、存储空间名称、可选的endpoint以及资源组ID
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)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
parser.add_argument('--resource_group_id',
                    help='The ID of the resource group to which the bucket belongs. (Optional, default is an empty string)',
                    default='')

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客户端,准备与OSS交互
    client = oss.Client(cfg)

    # 发送请求以设置指定存储空间的资源组配置
    result = client.put_bucket_resource_group(oss.PutBucketResourceGroupRequest(
            bucket=args.bucket,  # 存储空间名
            bucket_resource_group_configuration=oss.BucketResourceGroupConfiguration(
                resource_group_id=args.resource_group_id,  # 资源组ID
            ),
    ))

    # 打印操作结果的状态码和请求ID,以便确认请求状态
    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          )

# 当此脚本被直接执行时,调用main函数开始处理逻辑
if __name__ == "__main__":
    main()  # 脚本入口点,控制程序流程从这里开始

使用命令行工具ossutil

您可以使用命令行工具ossutil配置资源组,ossutil的安装请参见安装ossutil

以下命令用于配置存储空间examplebucket资源组IDrg-123

ossutil api put-bucket-resource-group --bucket examplebucket --resource-group-configuration "{\"ResourceGroupId\":\"rg-123\"}"

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

相关API

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

  • 本页导读 (1)
  • 背景信息
  • 注意事项
  • 操作方式
  • 使用OSS控制台
  • 使用阿里云SDK
  • 使用命令行工具ossutil
  • 相关API