通过Bucket Policy授权访问OSS
OSS支持面向资源的授权方式,允许在Bucket级别而不是用户级别设置权限策略。使用Bucket Policy可以授权当前云账号或者其他阿里云账号下单个或多个RAM用户、RAM角色等访问Bucket内的指定资源。Bucket Policy除提供策略语法的授权方式以外,还提供了图形化界面的授权方式,助力您结合业务场景,快速完成授权。
注意事项
Bucket Owner可以在OSS控制台通过图形化和策略语法两种方式配置Bucket Policy。通过策略语法的方式配置Bucket Policy前,您需要先了解OSS Action、Resource以及Condition分类信息。更多信息,请参见RAM Policy。
配置Bucket Policy时,如果授权用户选择了包含匿名请求在内的所有账号(*),且不包含Condition的情况下,则Bucket Policy仅对Bucket Owner以外的所有用户生效。如果授权用户选择了包含匿名请求在内的所有账号(*),且包含Condition的情况下,则Bucket Policy会对包含Bucket Owner在内的所有用户生效。
您可以添加多条Bucket Policy,但所有Bucket Policy的大小不允许超过16 KB。
使用场景
Bucket Policy通常应用于以下场景的授权访问:
需要进行跨账号或对指定用户授权访问或管理整个Bucket或Bucket内的部分资源。
需要对同账号下的不同RAM用户授予访问或管理Bucket资源的不同权限,例如只读、读写或完全控制的权限。
操作步骤
使用OSS控制台
方式一:图形化配置Bucket Policy
单击Bucket 列表,然后单击目标Bucket名称。
在左侧导航栏,选择权限控制>Bucket 授权策略。
在Bucket 授权策略页面的按图形策略添加页签,单击新增授权。
在新增授权面板,按以下说明配置各项参数,然后单击确定。
配置项
说明
授权资源
授权整个Bucket或Bucket内的部分资源供其他用户访问。
整个Bucket:授权策略针对整个Bucket生效。
指定资源:授权策略只针对指定的资源生效。您可以配置多条针对指定资源的授权策略。
针对目录级别授权
授权访问目录下的所有子目录和文件时,需在目录结尾处加上通配符星号(*)。例如授权访问abc目录下的所有子目录和文件,则填写为
abc/*
。针对指定文件授权
授权访问目录下的指定文件时,需填写不包含Bucket名称在内的文件的完整路径,例如授权访问abc目录下的myphoto.png文件,则填写为
abc/myphoto.png
。
授权用户
通过选择不同类型的账号将资源授权给不同用户进行访问。
所有账号(*):如果您需要给所有用户授权访问指定资源,请选中此项。
子账号:如果您需要给当前账号下的RAM用户授权访问指定资源,请选中此项,并从下拉菜单中选择目标RAM用户。如果需要授权的RAM用户较多时,建议直接在搜索框输入RAM用户名称关键字进行模糊匹配。
重要您的账号必须是阿里云账号或拥有此Bucket管理权限及RAM控制台ListUsers权限的RAM用户,否则无法查看当前账号的RAM用户列表。关于为RAM用户授予ListUsers权限的具体操作请参见为RAM用户授权。
其他账号:如果您需要给其他阿里云账号、RAM用户以及RAM角色授予访问权限,请选中此项。
当您需要给其他阿里云账号或RAM用户授权时,请输入被授权账号的UID。
当您需要给RAM角色授权时,输入格式为
arn:sts::{RoleOwnerUid}:assumed-role/{RoleName}/{RoleSessionName}
。例如扮演的RAM角色为testrole,角色拥有者的账号UID为137918634953xxxx
,角色会话名称RoleSessionName为testsession。此时应填写arn:sts::137918634953xxxx:assumed-role/testrole/testsession
。当您需要给所有RAM角色授权时,请使用通配符星号(*)。例如配置为arn:sts::*:*/*/*
。更多信息,请参见AssumeRole - 获取扮演角色的临时身份凭证。
重要当被授权的对象是RAM角色时,该账号无法通过OSS控制台访问授权资源,您可以通过命令行工具ossutil、OSS SDK、OSS API访问授权资源。例如,通过命令行工具ossutil访问授权资源时,您需要参考使用临时Token访问的方式配置访问凭证,然后通过请求OSS资源验证Bucket Policy配置是否生效。
授权操作
您可以通过简单设置和高级设置两种方式进行授权操作。
简单设置
选中此项后,您可以结合实际场景按照如下说明配置相应的访问权限。将鼠标悬停在每一种访问权限右侧对应的,可获取各访问权限对应的Action列表。
只读(不包含ListObject操作):对相关资源拥有查看和下载的权限。
只读(包含ListObject操作):对相关资源拥有查看、列举和下载的权限。
读/写:对相关资源有读和写权限。
完全控制:对相关资源有读、写、删除等所有操作权限。
拒绝访问:拒绝对相关资源的所有操作。
重要为确保使用OSS-HDFS服务的用户可正常访问OSS-HDFS的数据存储目录
.dlsdata/
及目录下的任意Object,对开通了OSS-HDFS服务的Bucket配置Bucket Policy时,请确保授权操作不能选择拒绝访问。如果针对某用户同时配置了多条Bucket Policy规则,则该用户所拥有的权限是所有Policy规则的叠加。当这些Bucket Policy中包含拒绝访问权限时,遵循拒绝访问权限优先原则。例如针对某用户第一次设置了只读权限,第二次设置了读/写权限,则该用户最终的权限为读/写。如果第三次设置了拒绝访问权限,则该用户最终的权限为拒绝访问。
只读、读/写、完全控制对应的授权效力为Allow,拒绝访问对应的授权效力为Deny。
高级设置
选中此项后,您需要根据以下说明完成相关配置。
效力:包含允许(Allow)和拒绝(Deny)两种授权效力。
操作:支持配置所有OSS支持的Action。关于Action分类的更多信息,请参见RAM Policy。
条件(可选)
您还可以在基础设置和高级设置模式下选中此项,用于限定只有满足条件的用户能够访问OSS资源。
访问方式:默认支持HTTP和HTTPS两种访问方式。如果您希望当前授权策略通过HTTPS的方式来访问Bucket资源,请选择HTTPS。如果您希望当前授权策略通过HTTP的方式来访问Bucket资源,请选择HTTP。相对于HTTP,HTTPS具有更高的安全性。
如果您需要强制Bucket内资源的所有请求访问方式为其中一种,例如HTTPS,您需要通过策略语法的方式来实现。具体操作,请参见如何配置HTTPS请求和证书?。
IP =:设置IP等于某个IP地址或IP地址段。如果有多个IP地址,各个IP地址之间用半角逗号(,)分隔。
IP ≠:设置IP不等于某个IP地址或IP地址段。如果有多个IP地址,各个IP地址之间用半角逗号(,)分隔 。
VPC=:设置只允许通过某个VPC或者某些VPC访问资源。支持选择当前账号下已创建的专有云网络VPC ID,也可以通过单击输入其他VPC账号后填写当前账号或其他账号创建的VPC ID。关于创建专有网络的具体操作,请参见创建专有网络和交换机。
VPC ≠:设置不允许通过某个VPC访问资源。支持选择当前账号下已创建的专有云网络VPC ID,也可以通过单击输入其他VPC账号后填写当前账号或其他账号创建的VPC ID。关于创建专有网络的具体操作,请参见创建专有网络和交换机。
说明如果Bucket Policy同时选择了VPC(包括等于或者不等于)和IP(包括等于或者不等于)的条件,则VPC和IP之间是and的关系,即Bucket Policy必须同时满足指定的VPC和IP。
单击确定。
方式二:通过策略语法配置Bucket Policy
在左侧导航栏,选择权限控制>Bucket 授权策略。
在Bucket 授权策略页面的按语法策略添加页签,单击编辑。
在语法策略输入框中,输入Bucket Policy。
您可以根据实际使用场景,编辑不同的策略语法,用于实现更精细的权限管理。以下为资源拥有者(UID为
174649585760xxxx
)为不同授权场景配置的Bucket Policy示例。示例1:允许所有用户列举存储空间examplebucket下所有文件的权限。
{ "Statement": [ { "Action": [ "oss:ListObjects", "oss:ListObjectVersions" ], "Effect": "Allow", "Principal": [ "*" ], "Resource": [ "acs:oss:*:174649585760xxxx:examplebucket" ] }, ], "Version": "1" }
示例2:拒绝源IP地址不在
192.168.0.0/16
范围内的所有用户对存储空间examplebucket执行任何操作。{ "Version": "1", "Statement": [ { "Effect": "Deny", "Action": "oss:*", "Principal": [ "*" ], "Resource": [ "acs:oss:*:174649585760xxxx:examplebucket" ], "Condition":{ "NotIpAddress": { "acs:SourceIp": ["192.168.0.0/16"] } } } ] }
示例3:允许指定的RAM用户(UID为
20214760404935xxxx
)拥有目标存储空间examplebucket下hangzhou/2020
和hangzhou/2015
目录的只读权限。{ "Statement": [ { "Action": [ "oss:GetObject", "oss:GetObjectAcl", "oss:GetObjectVersion", "oss:GetObjectVersionAcl" ], "Effect": "Allow", "Principal": [ "20214760404935xxxx" ], "Resource": [ "acs:oss:*:174649585760xxxx:examplebucket/hangzhou/2020/*", "acs:oss:*:174649585760xxxx:examplebucket/hangzhou/2015/*" ] }, { "Action": [ "oss:ListObjects", "oss:ListObjectVersions" ], "Condition": { "StringLike": { "oss:Prefix": [ "hangzhou/2020/*", "hangzhou/2015/*" ] } }, "Effect": "Allow", "Principal": [ "20214760404935xxxx" ], "Resource": [ "acs:oss:*:174649585760xxxx:examplebucket" ] } ], "Version": "1" }
单击保存后,在弹出的对话框,单击确定。
使用图形化管理工具ossbrowser
ossbrowser支持Bucket级别的操作与控制台支持的操作类似,请按照ossbrowser界面指引完成修改Bucket Policy的操作。关于使用ossbrowser的更多信息,请参见快速使用ossbrowser。
使用阿里云SDK
以下仅列举常见SDK的配置Bucket Policy的代码示例。关于其他SDK的配置Bucket Policy的代码示例,请参见SDK简介。
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
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";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
try {
// 以下示例用于资源拥有者(即UID为174649585760xxxx的Bucket Owner)通过Bucket Policy授权指定用户(UID为20214760404935xxxx的RAM用户)拥有列举examplebucket下所有文件的权限。
String policyText = "{\"Statement\": [{\"Effect\": \"Allow\", \"Action\": [\"oss:GetObject\", \"oss:ListObjects\"], \"Principal\": [\"20214760404935xxxx\"], \"Resource\": [\"acs:oss:*:174649585760xxxx:examplebucket/*\"]}], \"Version\": \"1\"}";
// 设置Bucket Policy。
ossClient.setBucketPolicy(bucketName, policyText);
} 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();
}
}
}
}
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\Core\OssException;
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
$provider = new EnvironmentVariableCredentialsProvider();
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 填写存储空间名称,例如examplebucket。
$bucket= "examplebucket";
// 以下示例用于资源拥有者(即UID为174649585760xxxx的Bucket Owner)通过Bucket Policy授权指定用户(UID为20214760404935xxxx的RAM用户)拥有列举examplebucket下所有文件的权限。
$policy = <<< BBBB
{
"Version":"1",
"Statement":[
{
"Action":[
"oss:GetObject",
"oss:ListObjects"
],
"Principal": [
"20214760404935xxxx"
],
"Effect":"Allow",
"Resource":["acs:oss:*:174649585760xxxx:examplebucket/*"]
}
]
}
BBBB;
try {
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
);
$ossClient = new OssClient($config);
// 设置Bucket Policy。
$ossClient->putBucketPolicy($bucket, $policy);
} catch (OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
print(__FUNCTION__ . ": OK" . "\n");
const OSS = require('ali-oss')
const client = new OSS({
// yourregion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
region: 'yourregion',
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
accessKeyId: process.env.OSS_ACCESS_KEY_ID,
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
// 填写存储空间名称,例如examplebucket。
bucket: 'examplebucket'
});
// 以下示例用于资源拥有者(即UID为174649585760xxxx的Bucket Owner)通过Bucket Policy授权指定用户(UID为20214760404935xxxx的RAM用户)拥有列举examplebucket下所有文件的权限。
const policy = {
Version: '1',
Statement: [
{
Action: ['oss:ListObjects', 'oss:GetObject'],
Effect: 'Allow',
Principal: ['20214760404935xxxx'],
Resource: ['acs:oss:*:174649585760xxxx:examplebucket']
}
]
};
async function putPolicy() {
const result = await client.putBucketPolicy('examplebucket', policy);
console.log(result)
}
putPolicy()
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
import json
# 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
# yourBucketName填写Bucket名称。
bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')
# 以下示例用于资源拥有者(即UID为174649585760xxxx的Bucket Owner)通过Bucket Policy授权指定用户(UID为20214760404935xxxx的RAM用户)拥有列举examplebucket下所有文件的权限。
policy_text = '{"Statement": [{"Effect": "Allow", "Action": ["oss:GetObject", "oss:ListObjects"], "Principal": ["20214760404935xxxx"], "Resource": ["acs:oss:*:174649585760xxxx:examplebucket/*"]}], "Version": "1"}'
# 上传授权策略。
bucket.put_bucket_policy(policy_text)
using Aliyun.OSS;
using Aliyun.OSS.Common;
// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "yourEndpoint";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填写Bucket名称。
var bucketName = "examplebucket";
// 创建OSSClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
// 以下示例用于资源拥有者(即UID为174649585760xxxx的Bucket Owner)通过Bucket Policy授权指定用户(UID为20214760404935xxxx的RAM用户)拥有列举examplebucket下所有文件的权限。
string policy = "{\"Version\":\"1\",\"Statement\":[{\"Action\":[\"oss:ListObjects\",\"oss:GetObject\"], \"Principal": \"20214760404935xxxx"\, \"Resource\": \"acs:oss:*:174649585760xxxx:examplebucket\*",\"Effect\": \"Allow\"}]}\n";
var request = new SetBucketPolicyRequest(bucketName, policy);
client.SetBucketPolicy(request);
Console.WriteLine("Set bucket:{0} Policy succeeded ", bucketName);
}
catch (OssException ex)
{
Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
Console.WriteLine("Failed with error info: {0}", ex.Message);
}
package main
import (
"fmt"
"os"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 创建OSSClient实例。
// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 以下示例用于资源拥有者(即UID为174649585760xxxx的Bucket Owner)通过Bucket Policy授权指定用户(UID为20214760404935xxxx的RAM用户)拥有列举examplebucket下所有文件的权限。
policyConfig := `
{
"Statement": [
{
"Action": [
"oss:GetObject",
"oss:ListObjects"
],
"Principal": [
"20214760404935xxxx"
],
"Effect" : "Allow",
"Resource" : ["acs:oss:*:174649585760xxxx:examplebucket/*"]
}
],
"Version": "1"
}`
// 设置Bucket Policy。
err = client.SetBucketPolicy("examplebucket", policyConfig)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
fmt.Println("SetBucketPolicy success")
}
#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";
/* 填写Bucket名称,例如examplebucket。*/
std::string BucketName = "examplebucket";
/* 初始化网络等资源。*/
InitializeSdk();
ClientConfiguration conf;
/* 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
/* 以下示例用于资源拥有者(即UID为174649585760xxxx的Bucket Owner)通过Bucket Policy授权指定用户(UID为20214760404935xxxx的RAM用户)拥有列举examplebucket下所有文件的权限。*/
std::string policy =
R"(
{
"Statement": [
{
"Action": [
"oss:GetObject",
"oss:ListObjects"
],
"Principal": [
"20214760404935xxxx"
],
"Effect" : "Allow",
"Resource" : ["acs:oss:*:174649585760xxxx:examplebucket/*"]
}
],
"Version": "1"
}
)";
SetBucketPolicyRequest request(BucketName);
request.setPolicy(policy);
auto outcome = client.SetBucketPolicy(request);
if (!outcome.isSuccess()) {
/* 异常处理。*/
std::cout << "Set Bucket Policy fail" <<
",code:" << outcome.error().Code() <<
",message:" << outcome.error().Message() <<
",requestId:" << outcome.error().RequestId() << std::endl;
}
/* 释放网络等资源。*/
ShutdownSdk();
return 0;
}
使用命令行工具ossutil
关于使用ossutil设置或修改Bucket Policy的具体操作,请参见bucket-policy(授权策略)。
使用REST API
如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。更多信息,请参见PutBucketPolicy。
访问授权资源
Bucket Policy配置完成后,您可以通过以下方式访问授权资源:
文件URL(仅当授权对象为所有用户时)
在浏览器上,使用Bucket默认域名或自有域名加文件路径进行访问。例如
http://mybucket.oss-cn-beijing.aliyuncs.com/file/myphoto.png
。更多信息,请参见OSS访问域名使用规则。控制台
登录OSS控制台,在左侧导航栏单击我收藏的路径右侧的加号(+),添加授权访问的Bucket和文件路径。具体操作,请参见访问路径。
命令行工具ossutil
使用被授权的账号通过ossutil访问授权资源。具体操作,请参见ossutil。
图形化工具ossbrowser
使用被授权的账号登录ossbrowser,登录时在预设OSS路径栏输入被授权访问的文件目录。具体操作,请参见ossbrowser。
OSS SDK
支持通过Java、PHP、Node.js、Python、Browser.js、.NET、Android、Go、iOS、C++、C SDK访问授权资源。