
# 对象owner给桶owner授予对象的完全控制权限（对象owner和桶owner不属于同一个账号）
本案例介绍当桶中对象来源于其他账号（非桶owner上传）时，桶owner如何获取对象的完全控制权限，即对象owner如何给桶owner授予对象的完全控制权限。例如账号A将对象a上传到账号B的桶b中，如何给账号B授予对象a的完全控制权限。
#### 场景介绍
在使用云服务的过程中，您可能会遇到如下场景：
- **跨账号上传对象后，基于业务诉求，桶owner需要访问和分析对象** **：**桶中的数据需要多个账号进行写入，之后桶owner需要对桶中数据进行访问和分析。例如跨账号的日志存储场景，假设您拥有3个账号，账号A、B用于运行业务生成日志，账号C用于收集和分析日志。账号A、B在使用云服务例如ELB、OBS等的过程中产生的日志文件会统一集中存储到账号C的日志存储桶中，之后账号C需要访问并分析这些日志文件。
- **跨账号上传对象后，桶owner需管理对象** **：**由于业务需要，您的桶可能会涉及到多个账号进行写入，作为桶owner您需要对桶中对象进行统一管理。例如：1）其余账号上传时可能意外将对象设置为公开读，桶owner需要将对象访问权限修正为私有；2）其他账号上传对象后，为了节省成本桶owner需要删除或修改对象的存储类别，或者使用生命周期定期删除、转换对象的存储类别；3）其他账号上传对象后，桶owner需要检查对象是否合规，如不符合要求需要删除。
在以上场景中，桶中的对象虽然并非桶owner上传，但是基于业务和管理的需要，桶owner需要拥有对象的访问和管理权限，OBS支持使用对象ACL完成对象owner对桶owner的授权。
#### 背景介绍
在进行授权操作前，您可能想要了解以下背景知识：
- **桶owner（桶拥有者）**：创建存储桶的IAM用户。
- **对象owner（对象拥有者）**：上传对象的IAM用户。当用户A向另一个用户B的桶中上传对象时，用户A是该对象的拥有者。这意味着即使桶属于用户B，用户B也默认没有权限访问或管理这个对象。
- **对象ACL** ：一种访问控制方式，用于对象owner给其他账号配置对象的访问权限。了解更多请参见[ACL](https://support.huaweicloud.com/perms-cfg-obs/obs_40_0005.html)。
- **bucket-owner-full-control** ：是对象ACL的一个配置选项。如果您作为对象owner将对象的ACL配置为bucket-owner-full-control，那么就意味着您将该对象的完全控制权授予了桶owner（对象所在桶的桶owner）。授权后，桶owner可以为自己授予对象所有操作的权限，也可以授予其他用户对象的访问权限。了解更多请参见[如何设置ACL](https://support.huaweicloud.com/perms-cfg-obs/obs_40_0005.html#obs_40_0005__section1234082716577)。
- **桶策略：** 除了ACL，桶策略是另外一种OBS的权限管理方式，桶owner可以使用桶策略配置的桶及桶内对象的访问权限。了解更多请参见[桶策略](https://support.huaweicloud.com/perms-cfg-obs/obs_40_0004.html)。
 
#### 方案架构
图1对象owner授权其他账号对象的访问权限   
![](https://support.huaweicloud.com/perms-cfg-obs/figure/zh-cn_image_0000002494370721.png)
如[图1]所示，账号A上传对象a到账号B的桶b中，此时账号A是对象a的对象owner，账号B是桶b的桶owner：
- **授权前**：账号B访问对象a会失败，报错403权限不足，原因是对象默认只有对象owner才能访问。
- **授权后** ：账号A将对象a的对象ACL配置为**bucket-owner-full-control**，配置后账号B拥有对象a的完全控制权。账号B自己可以访问和管理对象a，也可以授权其他用户访问对象a。
 
#### 配置流程
图2配置流程   
![](https://support.huaweicloud.com/perms-cfg-obs/figure/zh-cn_image_0000002461845636.png)
表1配置流程 
| 序号 | 操作步骤              | 说明                                                                                                                                                                                                                                                                                                                                    | 详细操作                                                                                          |
|:---|:---|:---|:---|
| 1  | 准备工作              | 桶owner通过**桶策略**为对象owner开通上传对象（obs:object:PutObject）的权限。                                                                                                                                                                                                                                                                               | [步骤一：准备工作]                               |
| 2  | 对象owner配置对象ACL    | 对象owner将对象的ACL设置为bucket-owner-full-control，配置后桶owner拥有对象的完全控制权                                                                                                                                                                                                                                                                        | [步骤二：为桶owner授予bucket-owner-full-control权限] |
| 3  | 【可选】桶owner使用桶策略授权 | 当**桶owner** 作为访问者时，若操作不涉及**修改对象元数据或增删改对象标签** ，可直接访问或管理对象；若操作涉及上述内容，则需通过**桶策略** 为自己授予[对应的权限](https://support.huaweicloud.com/api-obs/obs_04_0112.html)。 如果访问者**既不是桶owner也不是对象owner** ，那么桶owner需要使用**桶策略** 为访问者授予[对象操作对应的权限](https://support.huaweicloud.com/api-obs/obs_04_0112.html)。 | [【可选】步骤三：桶owner使用桶策略授权]                  |
| 4  | 访问或修改对象           | 桶owner或其他用户在授权后可正常访问或修改对象。                                                                                                                                                                                                                                                                                                            | [步骤四：访问或修改对象]                             |
   
 #### 步骤一：准备工作
为了使其他账号能够向您的桶中上传对象，您需要为这些账号授予上传权限，即桶owner需要为对象owner开通上传对象（obs:object:PutObject）的权限。例如账号A需要上传对象a到账号B的桶b中，那么账号B需要给账号A授予向桶b中上传对象的权限，如何授权请参考[对其他账号下的IAM用户授予桶和桶内资源的访问权限](https://support.huaweicloud.com/perms-cfg-obs/obs_40_0027.html)。
 #### 步骤二：为桶owner授予bucket-owner-full-control权限
您可以在上传对象时直接授权，此处以对象owner将名为exampleobject-a的对象，上传到名为examplebucket的桶中为例，在上传对象的同时将对象的ACL配置为owner bucket-owner-full-control。
您可以使用[管理控制台](https://console.huaweicloud.com/console/?locale=zh-cn#/obs/manager/buckets)、API、SDK、OBS Browser+、obsutil设置对象的ACL为bucket-owner-full-control：
#### 使用OBS控制台
OBS控制台仅支持在对象上传之后，针对已有对象，将对象ACL设置为bucket-owner-full-control。以下步骤请以**"桶owner"**的身份登录控制台操作：
1. 在OBS[管理控制台](https://console.huaweicloud.com/console/?locale=zh-cn#/obs/manager/buckets)左侧导航栏选择"桶列表"。
2. 在桶列表中，单击待操作的桶，进入"对象"页面。
3. 在左侧导航栏，单击"权限控制 \> 桶ACLs"。
4. 在"桶ACLs"中，单击拥有者所在行的"编辑"。 
   ![](https://support.huaweicloud.com/perms-cfg-obs/figure/zh-cn_image_0000002509405451.png)
   
   
5. 在弹窗中，勾选"对象读权限"，单击"确定"。 
   ![](https://support.huaweicloud.com/perms-cfg-obs/figure/zh-cn_image_0000002477485824.png)
   
   
6. 在左侧导航栏，单击"对象"，进入对象列表页。
7. 单击要配置对象的"对象名"，进入对象详情页面。单击对象ACL，进入对象ACL页签。
8. 单击"增加"，在弹窗中输入**桶owner** 的账号ID，勾选"对象访问权限\>读取权限"，"ACL访问权限\>读取权限"，"ACL访问权限\>写入权限"。如何获取账号ID请参见[获取账号ID](https://support.huaweicloud.com/api-iam/iam_17_0002.html)。
   
   ![](https://support.huaweicloud.com/perms-cfg-obs/figure/zh-cn_image_0000002477801204.png)
   
   
9. 在弹窗中单击确定，完成将对象ACL配置为bucket-owner-full-control。
 
#### 使用OBS API
使用OBS SDK您可以在上传对象时设置对象ACL，也可以设置已有对象的ACL，以下API请以**"对象owner"**的身份调用：
- 上传对象时设置对象ACL：[上传对象](https://support.huaweicloud.com/api-obs/obs_04_0080.html)
- 设置已有对象的ACL：[设置对象ACL](https://support.huaweicloud.com/api-obs/obs_04_0089.html)
 
#### 使用OBS SDK
使用SDK您可以在上传对象时设置对象ACL，也可以设置已有对象的ACL。以下接口请以**"对象owner"**的身份调用：
| 上传时设置对象ACL | [Java](https://support.huaweicloud.com/sdk-java-devg-obs/obs_21_0600.html) | [Python](https://support.huaweicloud.com/sdk-python-devg-obs/obs_22_0501.html) | [C](https://support.huaweicloud.com/sdk-c-devg-obs/obs_20_0400.html) | [Go](https://support.huaweicloud.com/sdk-go-devg-obs/obs_23_0401.html) | [BrowserJS](https://support.huaweicloud.com/sdk-browserjs-devg-obs/obs_24_0501.html) | [.NET](https://support.huaweicloud.com/sdk-dotnet-devg-obs/obs_25_0401.html) | [Android](https://support.huaweicloud.com/sdk-android-devg-obs/obs_26_0401.html) | [iOS](https://support.huaweicloud.com/sdk-ios-devg-obs/obs_27_0401.html) | [PHP](https://support.huaweicloud.com/sdk-php-devg-obs/obs_28_0401.html) | [Node.js](https://support.huaweicloud.com/sdk-nodejs-devg-obs/obs_29_0401.html) |
|---|---|---|---|---|---|---|---|---|---|---|
| 设置已有对象的ACL | [Java](https://support.huaweicloud.com/sdk-java-devg-obs/obs_21_0802.html) | [Python](https://support.huaweicloud.com/sdk-python-devg-obs/obs_22_0922.html) | [C](https://support.huaweicloud.com/sdk-c-devg-obs/obs_20_0314.html) | [Go](https://support.huaweicloud.com/sdk-go-devg-obs/obs_33_0509.html) | [BrowserJS](https://support.huaweicloud.com/sdk-browserjs-devg-obs/obs_24_0702.html) | [.NET](https://support.huaweicloud.com/sdk-dotnet-devg-obs/obs_25_0602.html) | [Android](https://support.huaweicloud.com/sdk-android-devg-obs/obs_26_0602.html) | [iOS](https://support.huaweicloud.com/sdk-ios-devg-obs/obs_27_0602.html) | [PHP](https://support.huaweicloud.com/sdk-php-devg-obs/obs_28_0602.html) | [Node.js](https://support.huaweicloud.com/sdk-nodejs-devg-obs/obs_29_0604.html) |
   
以Java、Python两种语言为例，示例代码如下：
**上传时直接设置对象ACL（Java）**
您可以在上传对象时授予桶owner完全控制权限。此处以对象owner上传对象exampleobject-a时设置对象ACL为bucket-owner-full-control为例。
```
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.AccessControlList;
import com.obs.services.model.PutObjectRequest;
import java.io.File;
public class PutObject012 {
    public static void main(String[] args) {
        // 此处的AK/SK是对象owner的AK/SK
        // 您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入。如果使用硬编码可能会存在泄露风险。
        // 您可以登录访问管理控制台获取访问密钥AK/SK
        String ak = System.getenv("ACCESS_KEY_ID");
        String sk = System.getenv("SECRET_ACCESS_KEY_ID");
        // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。
        // 您可以通过环境变量获取访问密钥AK/SK/SecurityToken，也可以使用其他外部引入方式传入。
        // String securityToken = System.getenv("SECURITY_TOKEN");
        // endpoint填写桶所在的endpoint, 此处以华北-北京四为例，其他地区请按实际情况填写。
        String endPoint = "https://obs.cn-north-4.myhuaweicloud.com";
        // 您可以通过环境变量获取endPoint，也可以使用其他外部引入方式传入。
        //String endPoint = System.getenv("ENDPOINT");
        // 创建ObsClient实例
        // 使用永久AK/SK初始化客户端
        ObsClient obsClient = new ObsClient(ak, sk,endPoint);
        // 使用临时AK/SK和SecurityToken初始化客户端
        // ObsClient obsClient = new ObsClient(ak, sk, securityToken, endPoint);
        try {
            // 上传对象时指定预定义ACL
            PutObjectRequest request = new PutObjectRequest();
            request.setBucketName("examplebucket");
            request.setObjectKey("exampleobject-a");
            request.setFile(new File("localfile"));
            // 设置对象ACL为bucket-owner-full-control
            request.setAcl(AccessControlList.REST_CANNED_BUCKET_OWNER_FULL_CONTROL);
            obsClient.putObject(request);
            System.out.println("putObject successfully");
        } catch (ObsException e) {
            System.out.println("putObject failed");
            // 请求失败,打印http状态码
            System.out.println("HTTP Code:" + e.getResponseCode());
            // 请求失败,打印服务端错误码
            System.out.println("Error Code:" + e.getErrorCode());
            // 请求失败,打印详细错误信息
            System.out.println("Error Message:" + e.getErrorMessage());
            // 请求失败,打印请求id
            System.out.println("Request ID:" + e.getErrorRequestId());
            System.out.println("Host ID:" + e.getErrorHostId());
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("putObject failed");
            // 其他异常信息打印
            e.printStackTrace();
        }
    }
}
```
**上传时直接设置对象ACL（Python）**
您可以在上传对象时授予桶owner完全控制权限。此处以对象owner上传对象exampleobject-a时设置对象ACL为bucket-owner-full-control为例。
```
from obs import ObsClient
from obs import PutObjectHeader
import os
import traceback
# 此处的AccessKeyID和SecretAccessKey是对象owner的AccessKeyID和SecretAccessKey
# 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险
# 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html。
# 运行本代码示例之前，请确保已设置环境变量AccessKeyID和SecretAccessKey
ak = os.getenv("AccessKeyID")
sk = os.getenv("SecretAccessKey")
# 【可选】如果使用临时AKSK和SecurityToken访问OBS，则同样推荐通过环境变量获取
# security_token = os.getenv("SecurityToken")#  server填写Bucket对应的Endpoint, 这里以华北-北京四为例，其他地区请按实际情况填写
server = "https://obs.cn-north-4.myhuaweicloud.com"
# 创建obsClient实例
# 如果使用临时AKSK和SecurityToken访问OBS，需要在创建实例时通过security_token参数指定securityToken值
obsClient = ObsClient(access_key_id=ak, secret_access_key=sk, server=server)
try:
    # 上传对象的附加头域
    headers = PutObjectHeader()
    # 【可选】待上传对象的MIME类型
    headers.contentType = 'text/plain'
    # 设置对象ACL为bucket-owner-full-control
    headers.acl = 'bucket-owner-full-control'
    # 桶名
    bucketName = "examplebucket"
    # 对象名，即上传后的文件名
    objectKey = "exampleobject-a"
    # 待上传文件的完整路径，如aa/bb.txt
    file_path = 'localfile'
    # 上传文件的自定义元数据
    metadata = {'meta1': 'value1', 'meta2': 'value2'}
    # 文件上传
    resp = obsClient.putFile(bucketName, objectKey, file_path, metadata, headers)
    # 返回码为2xx时，接口调用成功，否则接口调用失败
    if resp.status < 300:
        print('Put File Succeeded')
        print('requestId:', resp.requestId)
        print('etag:', resp.body.etag)
        print('versionId:', resp.body.versionId)
        print('storageClass:', resp.body.storageClass)
    else:
        print('Put File Failed')
        print('requestId:', resp.requestId)
        print('errorCode:', resp.errorCode)
        print('errorMessage:', resp.errorMessage)
except:
    print('Put File Failed')
    print(traceback.format_exc())
```
**设置已有对象的ACL（Java）**
您也可以在对象上传完成后，针对已有对象授予桶owner完全控制权限。此处以对象owner配置已有对象exampleobject-a的ACL为bucket-owner-full-control为例。
```
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.AccessControlList;
public class SetObjectAcl001 {
    public static void main(String[] args) {
        // 此处的AK/SK是对象owner的AK/SK
        // 您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入。如果使用硬编码可能会存在泄露风险。
        // 您可以登录访问管理控制台获取访问密钥AK/SK
        String ak = System.getenv("ACCESS_KEY_ID");
        String sk = System.getenv("SECRET_ACCESS_KEY_ID");
        // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。
        // 您可以通过环境变量获取访问密钥AK/SK/SecurityToken，也可以使用其他外部引入方式传入。
        // String securityToken = System.getenv("SECURITY_TOKEN");
        // endpoint填写桶所在的endpoint, 此处以华北-北京四为例，其他地区请按实际情况填写。
        String endPoint = "https://obs.cn-north-4.myhuaweicloud.com";
        // 您可以通过环境变量获取endPoint，也可以使用其他外部引入方式传入。
        //String endPoint = System.getenv("ENDPOINT");
        // 创建ObsClient实例
        // 使用永久AK/SK初始化客户端
        ObsClient obsClient = new ObsClient(ak, sk,endPoint);
        // 使用临时AK/SK和SecurityToken初始化客户端
        // ObsClient obsClient = new ObsClient(ak, sk, securityToken, endPoint);
        try {
            // 为对象设置预定义ACL
            // 设置对象ACL为bucket-owner-full-control
            obsClient.setObjectAcl("examplebucket", "exampleobject-a", AccessControlList.REST_CANNED_BUCKET_OWNER_FULL_CONTROL);
            System.out.println("setObjectAcl successfully");
        } catch (ObsException e) {
            System.out.println("setObjectAcl failed");
            // 请求失败,打印http状态码
            System.out.println("HTTP Code:" + e.getResponseCode());
            // 请求失败,打印服务端错误码
            System.out.println("Error Code:" + e.getErrorCode());
            // 请求失败,打印详细错误信息
            System.out.println("Error Message:" + e.getErrorMessage());
            // 请求失败,打印请求id
            System.out.println("Request ID:" + e.getErrorRequestId());
            System.out.println("Host ID:" + e.getErrorHostId());
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("setObjectAcl failed");
            // 其他异常信息打印
            e.printStackTrace();
        }
    }
}
```
**设置已有对象的ACL（Python）**
您也可以在对象上传完成后，针对已有对象授予桶owner完全控制权限。此处以对象owner配置已有对象exampleobject-a的ACL为bucket-owner-full-control为例。
```
from obs import ObsClient
import os
from obs import ACL
from obs import Owner
from obs import Grant, Permission
from obs import Grantee
import traceback
# 此处的AccessKeyID和SecretAccessKey是对象owner的AK/SK
# 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险
# 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
ak = os.getenv("AccessKeyID")
sk = os.getenv("SecretAccessKey")
# 【可选】如果使用临时AKSK和SecurityToken访问OBS，则同样推荐通过环境变量获取
# security_token = os.getenv("SecurityToken")
# server填写Bucket对应的Endpoint, 这里以华北-北京四为例，其他地区请按实际情况填写
server = "https://obs.cn-north-4.myhuaweicloud.com"
# 创建obsClient实例
# 如果使用临时AKSK和SecurityToken访问OBS，需要在创建实例时通过security_token参数指定securityToken值
obsClient = ObsClient(access_key_id=ak, secret_access_key=sk, server=server)
try:
    # id为 对象owner的账号ID
    owner = Owner(owner_id='obj_owner_id')
    # id为 桶owner的账号ID
    grantee = Grantee(grantee_id='bkt_owner_id')
    # 设置对象ACL为bucket-owner-full-control
    grant0 = Grant(grantee=grantee, permission=Permission.FULL_CONTROL)
    # 设置acl
    acl = ACL(owner=owner, grants=[grant0])
    bucketName = "examplebucket"
    objectKey = "exampleobject-a"
    # 指定acl参数设置对象ACL
    resp = obsClient.setObjectAcl(bucketName, objectKey, acl)
    # 返回码为2xx时，接口调用成功，否则接口调用失败
    if resp.status < 300:
        print('Set Object Acl Succeeded')
        print('requestId:', resp.requestId)
    else:
        print('Set Object Acl Failed')
        print('requestId:', resp.requestId)
        print('errorCode:', resp.errorCode)
        print('errorMessage:', resp.errorMessage)
except:
    print('Set Object Acl Failed')
    print(traceback.format_exc())
```
#### 使用OBS Browser+
[OBS Browser+](https://support.huaweicloud.com/browsertg-obs/obs_03_1000.html)仅支持在对象上传时设置对象ACL。以下步骤请以**"对象owner"**的身份登录OBS Browser+操作：
因为对象owner和桶owner不属于同一个账号，所以上传对象前请先挂载外部桶：
1. 登录OBS Browser+。
2. 单击页面左边"外部桶"，如[图3]所示。
   
   图3外部桶   
   ![](https://support.huaweicloud.com/perms-cfg-obs/figure/zh-cn_image_0000001856024930.png)
   
   
3. 单击"挂载"，并在"桶名"输入框中，输入需要挂载的外部桶名称，并单击"确定"，如[图4]所示。
   
   图4挂载外部桶   
   ![](https://support.huaweicloud.com/perms-cfg-obs/figure/zh-cn_image_0000001199189848.png)
   "桶名"需全局唯一，桶命名规则如下：
   - 3～63个字符，数字或字母开头，支持小写字母、数字、"-"、"."。
   
   - 禁止使用IP地址。
   
   - 禁止以"-"或"."开头及结尾。
   
   - 禁止两个"."相邻（如："my..bucket"）。
   
   - 禁止"."和"-"相邻（如："my-.bucket"和"my.-bucket"）。
   
   
   当挂载外部桶成功后，用户可以在桶列表中查看到挂载的外部桶，并且对该桶有相应的ACL访问权限。
   
   
挂载完成后，上传对象并设置对象ACL：
1. 单击外部桶的桶名，进入外部桶的对象列表页。
2. 单击"上传"。
3. 在上传对象弹窗中配置对象ACL并发起上传。 
   "对象权限"选择"桶拥有者完全控制"，存储类别按需选择，单击"添加文件"选中要上传的文件。单击"确定"开始上传对象。
   ![](https://support.huaweicloud.com/perms-cfg-obs/figure/zh-cn_image_0000002510106783.png)
   
   
4. 上传成功后，外部桶的对象列表页，会出现新上传的对象。
 
#### 使用obsutil
使用obsutil您可以在上传对象时设置对象ACL，也可以设置已有对象的ACL，以下步骤请以**"对象owner"** 的身份操作（[obsutil初始化](https://support.huaweicloud.com/utiltg-obs/obs_11_0005.html)时，将AK/SK设置为对象owner的AK/SK）：
- 上传对象时设置对象ACL：[上传对象](https://support.huaweicloud.com/utiltg-obs/obs_11_0013.html)
- 设置已有对象的ACL：[设置对象ACL](https://support.huaweicloud.com/utiltg-obs/obs_11_0015.html)
 
 #### 【可选】步骤三：桶owner使用桶策略授权
- 如果访问者是**桶owner** 并且操作**不包含** 修改对象元数据或者增删改对象标签，那么桶owner可以直接访问或管理对象，无需进行桶策略授权，请直接进行[步骤四]。
- 如果访问者是**桶owner** ，并且操作包含[表3 需要进行桶策略授权的操作]中的操作，那么桶owner需要使用**桶策略**为自己授予相关操作的权限。
- 如果访问者**既不是桶owner也不是对象owner** ，那么桶owner需要使用**桶策略** 为访问者授予相关操作的权限。
   表2需要进行桶策略授权的操作 
  | 操作人              | 操作                | 授权项                                                                      |
  |:---|:---|:---|
  | 桶owner           | 修改对象元数据           | obs:object:modifyObjectMetadata                                          |
  | 桶owner           | 新建/修改对象标签（未开启多版本） | obs:object:putObjectTagging                                              |
  | 桶owner           | 新建/修改对象标签（开启多版本）  | obs:object:putObjectVersionTagging                                       |
  | 桶owner           | 删除对象标签（未开启多版本）    | obs:object:deleteObjectTagging                                           |
  | 桶owner           | 删除对象标签（开启多版本）     | obs:object:deleteObjectVersionTagging                                    |
  | 非桶owner且非对象owner | **所有操作都**需要桶策略授权  | [各个对象操作对应的授权项](https://support.huaweicloud.com/api-obs/obs_04_0112.html) |
     
  
OBS支持使用[管理控制台](https://support.huaweicloud.com/usermanual-obs/obs_03_0123.html)、[API](https://support.huaweicloud.com/api-obs/obs_04_0027.html)、[SDK](https://support.huaweicloud.com/sdkreference-obs/obs_02_0001.html)、[OBS Browser+](https://support.huaweicloud.com/browsertg-obs/obs_03_1055.html)、[obsutil](https://support.huaweicloud.com/utiltg-obs/obs_11_0406.html)设置桶策略，请以**"桶owner"**的身份执行本步骤。
此处以桶examplebucket的桶owner，使用桶策略授予exampleobject-a对象的对象元数据修改权限为例，提供以下示例代码供参考：
**Java示例代码：**
```
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
public class SetBucketPolicy001 {
    public static void main(String[] args) {
        // 此处的AK/SK是桶owner的AK/SK
        // 您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入。如果使用硬编码可能会存在泄露风险。
        // 您可以登录访问管理控制台获取访问密钥AK/SK
        String ak = System.getenv("ACCESS_KEY_ID");
        String sk = System.getenv("SECRET_ACCESS_KEY_ID");
        // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。
        // 您可以通过环境变量获取访问密钥AK/SK/SecurityToken，也可以使用其他外部引入方式传入。
        // String securityToken = System.getenv("SECURITY_TOKEN");
        // endpoint填写桶所在的endpoint, 此处以华北-北京四为例，其他地区请按实际情况填写。
        String endPoint = "https://obs.cn-north-4.myhuaweicloud.com";
        // 您可以通过环境变量获取endPoint，也可以使用其他外部引入方式传入。
        //String endPoint = System.getenv("ENDPOINT");
        // 创建ObsClient实例
        // 使用永久AK/SK初始化客户端
        ObsClient obsClient = new ObsClient(ak, sk,endPoint);
        // 使用临时AK/SK和SecurityToken初始化客户端
        // ObsClient obsClient = new ObsClient(ak, sk, securityToken, endPoint);
        try {
            // 示例桶名
            String exampleBucket = "examplebucket";
            // 示例桶策略，Principal字段填写被授权用户的账号ID（domainId）和IAM用户ID（userId），例如要给桶owner授权，就填写桶owner的账号ID和IAM用户ID，要给其他用户授权就填写对应用户的ID
            String examplePolicy ="{\"Statement\":[{\"Principal\":{\"ID\":[\"domain/YourDomainId:user/YourUserId\"]},\"Effect\":\"Allow\",\"Action\":[\"ModifyObjectMetaData\"],\"Resource\":\""
                    + exampleBucket
                    + "/exampleobject-a\"}]}";
            obsClient.setBucketPolicy(exampleBucket, examplePolicy);
            System.out.println("SetBucketPolicy successfully");
        } catch (ObsException e) {
            System.out.println("SetBucketPolicy failed");
            // 请求失败,打印http状态码
            System.out.println("HTTP Code:" + e.getResponseCode());
            // 请求失败,打印服务端错误码
            System.out.println("Error Code:" + e.getErrorCode());
            // 请求失败,打印详细错误信息
            System.out.println("Error Message:" + e.getErrorMessage());
            // 请求失败,打印请求id
            System.out.println("Request ID:" + e.getErrorRequestId());
            System.out.println("Host ID:" + e.getErrorHostId());
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("SetBucketPolicy failed");
            // 其他异常信息打印
            e.printStackTrace();
        }
    }
}
```
**Python示例代码：**
```
from obs import ObsClient
import os
import traceback
# 此处的AccessKeyID和SecretAccessKey是桶owner的AK/SK
# 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险
# 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
ak = os.getenv("AccessKeyID")
sk = os.getenv("SecretAccessKey")
# 【可选】如果使用临时AKSK和SecurityToken访问OBS，则同样推荐通过环境变量获取
# security_token = os.getenv("SecurityToken")
# server填写Bucket对应的Endpoint, 这里以华北-北京四为例，其他地区请按实际情况填写
server = "https://obs.cn-north-4.myhuaweicloud.com"
# 创建obsClient实例
# 如果使用临时AKSK和SecurityToken访问OBS，需要在创建实例时通过security_token参数指定securityToken值
obsClient = ObsClient(access_key_id=ak, secret_access_key=sk, server=server)
try:
    bucketName = "examplebucket"
    # 示例桶策略，Principal字段填写被授权用户的账号ID（domainId）和IAM用户ID（userId），例如要给桶owner授权，就填写桶owner的账号ID和IAM用户ID，要给其他用户授权就填写对应用户的ID
    policyJSON = '{"Statement":[{"Sid":"ExampleStatementID1","Effect":"Allow","Principal":{"ID":["domain/**********:user/**********"]},"Action":["ModifyObjectMetaData"],"Resource":["examplebucket/exampleobject-a"]}]}'
    # 设置桶策略
    resp = obsClient.setBucketPolicy(bucketName, policyJSON)
    # 返回码为2xx时，接口调用成功，否则接口调用失败
    if resp.status < 300:
        print('Set Bucket Policy Succeeded')
        print('requestId:', resp.requestId)
    else:
        print('Set Bucket Policy Failed')
        print('requestId:', resp.requestId)
        print('errorCode:', resp.errorCode)
        print('errorMessage:', resp.errorMessage)
except:
    print('Set Bucket Policy Failed')
    print(traceback.format_exc())
```
 #### 步骤四：访问或修改对象
桶owner或其他用户在授权后可正常访问或修改对象。OBS支持使用[管理控制台](https://support.huaweicloud.com/usermanual-obs/obs_03_0315.html)、[API](https://support.huaweicloud.com/api-obs/obs_04_0079.html)、[SDK](https://support.huaweicloud.com/sdkreference-obs/obs_02_0001.html)、[OBS Browser+](https://support.huaweicloud.com/browsertg-obs/obs_03_1059.html)、[obsutil](https://support.huaweicloud.com/utiltg-obs/obs_11_0012.html)访问或修改对象，请以**"桶owner或其他被授权用户"**的身份执行本步骤。
此处以桶owner修改examplebucket桶中exampleobject-a对象的存储类别（修改存储类别本质上是修改对象元数据）为例。
**Java示例代码：**
```
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.ObjectMetadata;
import com.obs.services.model.SetObjectMetadataRequest;
import java.util.HashMap;
public class SetObjectMetadata001 {
    public static void main(String[] args) {
        // 此处的AK/SK是被授予对象访问权限的用户的AK/SK，如果是桶owner被授权就是桶owner的AK/SK，如果是其他用户被授权，就是其他用户的AK/SK
        // 您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入。如果使用硬编码可能会存在泄露风险。
        // 您可以登录访问管理控制台获取访问密钥AK/SK
        String ak = System.getenv("ACCESS_KEY_ID");
        String sk = System.getenv("SECRET_ACCESS_KEY_ID");
        // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。
        // 您可以通过环境变量获取访问密钥AK/SK/SecurityToken，也可以使用其他外部引入方式传入。
        // String securityToken = System.getenv("SECURITY_TOKEN");
        // endpoint填写桶所在的endpoint, 此处以华北-北京四为例，其他地区请按实际情况填写。
        String endPoint = "https://obs.cn-north-4.myhuaweicloud.com";
        // 您可以通过环境变量获取endPoint，也可以使用其他外部引入方式传入。
        //String endPoint = System.getenv("ENDPOINT");
        // 创建ObsClient实例
        // 使用永久AK/SK初始化客户端
        ObsClient obsClient = new ObsClient(ak, sk,endPoint);
        // 使用临时AK/SK和SecurityToken初始化客户端
        // ObsClient obsClient = new ObsClient(ak, sk, securityToken, endPoint);
        try {
            // 设置对象元数据
            SetObjectMetadataRequest request = new SetObjectMetadataRequest("examplebucket", "exampleobject-a");
            // 设置桶的存储类别为标准存储
            request.setObjectStorageClass(StorageClassEnum.WARM);
            ObjectMetadata metadata = obsClient.setObjectMetadata(request);
            System.out.println("setObjectMetadata successfully");
            System.out.println("UserMetadata:" + metadata.toString());
        } catch (ObsException e) {
            System.out.println("setObjectMetadata failed");
            // 请求失败,打印http状态码
            System.out.println("HTTP Code:" + e.getResponseCode());
            // 请求失败,打印服务端错误码
            System.out.println("Error Code:" + e.getErrorCode());
            // 请求失败,打印详细错误信息
            System.out.println("Error Message:" + e.getErrorMessage());
            // 请求失败,打印请求id
            System.out.println("Request ID:" + e.getErrorRequestId());
            System.out.println("Host ID:" + e.getErrorHostId());
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("setObjectMetadata failed");
            // 其他异常信息打印
            e.printStackTrace();
        }
    }
}
```
**Python示例代码：**
```
from obs import SetObjectMetadataHeader
from obs import ObsClient
import os
import traceback
# 此处的AccessKeyID和SecretAccessKey是被授予对象访问权限的用户的AK/SK，如果是桶owner被授权就是桶owner的AK/SK，如果是其他用户被授权，就是其他用户的AK/SK
# 推荐通过环境变量获取AKSK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险
# 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
ak = os.getenv("AccessKeyID")
sk = os.getenv("SecretAccessKey")
# 【可选】如果使用临时AKSK和SecurityToken访问OBS，则同样推荐通过环境变量获取
# security_token = os.getenv("SecurityToken")
# server填写Bucket对应的Endpoint, 这里以华北-北京四为例，其他地区请按实际情况填写
server = "https://obs.cn-north-4.myhuaweicloud.com"
# 创建obsClient实例
# 如果使用临时AKSK和SecurityToken访问OBS，需要在创建实例时通过security_token参数指定securityToken值
obsClient = ObsClient(access_key_id=ak, secret_access_key=sk, server=server)
try:
    # 设置对象自定义元数据
    metadata = {'property1': 'property-value1', 'property2': 'property-value2'}
    # 设置对象附加头域
    headers = SetObjectMetadataHeader()
    # 【可选】待上传对象的MIME类型
    headers.contentType = "Your Content-Type"
    # 设置目标存储类别
    headers.storageClass = "WARM" 
    bucketName = "examplebucket"
    objectKey = "exampleobject-a"
    # 设置对象元数据
    resp = obsClient.setObjectMetadata(bucketName, objectKey, metadata, headers)
    # 返回码为2xx时，接口调用成功，否则接口调用失败
    if resp.status < 300:
        print('Set Object Metadata Succeeded')
        print('requestId:', resp.requestId)
    else:
        print('Set Object Metadata Failed')
        print('requestId:', resp.requestId)
        print('errorCode:', resp.errorCode)
        print('errorMessage:', resp.errorMessage)
except:
    print('Set Object Metadata Failed')
    print(traceback.format_exc())
```
