通過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訪問授權資源。