通過STS服務,您可以為使用者產生臨時訪問憑證,使其在有效期間內訪問受策略限制的OSS資源。超過有效期間後,憑證自動失效,無法繼續訪問OSS資源,確保了存取控制的靈活性和時效性。
使用情境
某電商企業A把海量商品資料存放在阿里雲OSS中。供應商企業B需要定期向A的OSS上傳資料,並通過自己的系統與企業A的阿里雲資源對接。
對於資訊安全方面,企業A有如下需求:
資料安全:企業A不希望將固定存取金鑰(AccessKey)泄露給企業B,以免核心資料被非法擷取和濫用。
許可權控制:企業A希望暫時僅賦予企業B上傳許可權,後續再根據需求對許可權進行動態調整,以實現對許可權的精準控制。
許可權管理:面對企業B以及後續的其他夥伴,企業A希望能夠靈活地為每個夥伴或臨時需求產生相應的憑證,而無需不斷管理和配置固定的存取金鑰(AccessKey)許可權。
限時存取控制:企業A希望根據企業B的具體需求,限制其對資料訪問的有效時間。到期後,企業B將自動失去存取權限,從而實現對資料互動時效性的嚴格控制。
方案概覽
企業A通過臨時訪問憑證授權企業B安全地將檔案上傳到OSS。
企業A需首先建立RAM使用者和RAM角色,並完成相關授權操作。之後,企業B向企業A申請臨時訪問憑證,企業A調用AssumeRole介面擷取STS臨時訪問憑證,然後將其傳遞給企業B。企業B拿到該憑證後,即可將資料上傳至企業A的OSS中。
前提條件
企業A已建立Bucket。具體操作,請參見建立儲存空間。
步驟一:企業A頒發臨時訪問憑證
1. 建立RAM使用者
使用阿里雲主帳號或擁有存取控制(RAM)系統管理權限的RAM帳號建立RAM使用者。
登入RAM控制台。
在左側導覽列,選擇身份管理>使用者。
單擊创建用户。
輸入登录名称和顯示名稱。
在访问方式地區下,選擇使用永久 AccessKey 訪問,然後單擊確定。
根據介面提示,完成安全驗證。
複製存取金鑰(AccessKey ID和AccessKey Secret)。
重要RAM使用者的AccessKey Secret只在建立時顯示,後續不支援查看,請妥善保管。
2. 為RAM使用者授予請求AssumeRole的許可權
建立完RAM使用者後,使用阿里雲主帳號或擁有存取控制(RAM)系統管理權限的RAM帳號授予該RAM使用者通過扮演角色調用STS服務的許可權。
單擊已建立RAM使用者右側對應的添加权限。
在新增授權頁面,選擇AliyunSTSAssumeRoleAccess系統策略。
說明授予RAM使用者調用STS服務AssumeRole介面的固定許可權是AliyunSTSAssumeRoleAccess,與後續擷取臨時訪問憑證以及通過臨時訪問憑證發起OSS請求要求的權限無關。
單擊確認新增授權。
3. 建立RAM角色
使用阿里雲主帳號或擁有存取控制(RAM)系統管理權限的RAM帳號建立RAM角色。用於定義RAM角色被扮演時,可以獲得OSS服務的哪些存取權限。
在左側導覽列,選擇身份管理>角色。
單擊创建角色,選擇可信實體類型為阿里云账号,單擊下一步。
在创建角色對話方塊,角色名称填寫為RamOssTest,选择信任的云账号為当前云账号。
單擊完成。角色建立完成後,單擊關閉。
在角色頁面,搜尋方塊輸入角色名稱RamOssTest,然後單擊RamOssTest。
單擊ARN右側的複製,儲存角色的ARN。
4. 為RAM角色授予上傳檔案的許可權
建立完RAM角色後,使用阿里雲主帳號或擁有存取控制(RAM)系統管理權限的RAM帳號為RAM角色附加一個或多個權限原則,明確RAM角色在被扮演時所能擁有的OSS資源存取權限。例如,如果希望RAM使用者在扮演該角色後只能向OSS指定Bucket上傳檔案,則需要為角色添加寫入許可權的策略。
建立上傳檔案的自訂權限原則。
在左側導覽列,選擇权限管理>权限策略。
在权限策略頁面,單擊创建权限策略。
在创建权限策略頁面,單擊指令碼編輯,然後在策略文檔輸入框中賦予角色上傳檔案到examplebucket的許可權。具體配置樣本如下。
警告以下樣本僅供參考。您需要根據實際需求配置更細粒度的授權策略,防止出現許可權過大的風險。關於更細粒度的授權策略配置詳情,請參見通過RAM或STS服務向其他使用者授權。
{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "oss:PutObject" ], "Resource": [ "acs:oss:*:*:examplebucket/*" ] } ] }
說明RAM角色所擁有的OSS許可權取決於Action的配置,例如授予oss:PutObject許可權,則RAM使用者在扮演RAM角色時可以對指定Bucket執行簡單上傳、表單上傳、追加上傳、分區上傳、斷點續傳上傳等操作。更多資訊,請參見OSS Action說明。
策略配置完成後,單擊繼續編輯基本資料。
在基本資料地區,填寫策略名稱為RamTestPolicy,然後單擊確定。
為RAM角色RamOssTest授予自訂權限原則。
在左側導覽列,選擇
。在角色頁面,找到目標RAM角色RamOssTest。
單擊RAM角色RamOssTest右側的新增授權。
在添加許可權頁面下的自訂策略頁簽,選擇已建立的自訂權限原則RamTestPolicy。
單擊確定。
5. 使用RAM使用者扮演RAM角色擷取臨時訪問憑證
STS臨時訪問憑證無法通過阿里雲主帳號的存取金鑰(AccessKey)調用STS API介面擷取,否則會導致報錯失敗。以下樣本將以使用RAM使用者的存取金鑰(AccessKey)為例進行操作。
為角色授予上傳檔案的許可權後,RAM使用者需要通過扮演角色來擷取臨時訪問憑證。臨時訪問憑證包括安全性權杖(SecurityToken)、臨時存取金鑰(AccessKeyId和AccessKeySecret)以及到期時間(Expiration)。您可以使用STS SDK擷取具有簡單上傳(
oss:PutObject
)許可權的臨時訪問憑證。有關更多語言的STS SDK樣本,請參見STS SDK概覽。範例程式碼中的endpoint為STS服務存取點地址。為了獲得更快的STS服務響應速度,您可以根據伺服器所處地區,選擇對應的或相近的STS服務存取點地址進行填寫。有關STS服務存取點地址資訊,請參見服務存取點。
Java
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
public class StsServiceSample {
public static void main(String[] args) {
// STS服務存取點,例如sts.cn-hangzhou.aliyuncs.com。您可以通過公網或者VPC接入STS服務。
String endpoint = "sts.cn-hangzhou.aliyuncs.com";
// 從環境變數中擷取步驟1.1產生的RAM使用者的存取金鑰(AccessKey ID和AccessKey Secret)。
String accessKeyId = System.getenv("ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ACCESS_KEY_SECRET");
// 從環境變數中擷取步驟1.3產生的RAM角色的RamRoleArn。
String roleArn = System.getenv("RAM_ROLE_ARN");
// 自訂角色會話名稱,用來區分不同的令牌,例如可填寫為SessionTest。
String roleSessionName = "yourRoleSessionName";
// 臨時訪問憑證將獲得角色擁有的所有許可權。
String policy = null;
// 臨時訪問憑證的有效時間,單位為秒。最小值為900,最大值以當前角色設定的最大會話時間為準。當前角色最大會話時間取值範圍為3600秒~43200秒,預設值為3600秒。
// 在上傳大檔案或者其他較耗時的使用情境中,建議合理設定臨時訪問憑證的有效時間,確保在完成目標任務前無需反覆調用STS服務以擷取臨時訪問憑證。
Long durationSeconds = 3600L;
try {
// 發起STS請求所在的地區。建議保留預設值,預設值為空白字串("")。
String regionId = "";
// 添加endpoint。適用於Java SDK 3.12.0及以上版本。
DefaultProfile.addEndpoint(regionId, "Sts", endpoint);
// 添加endpoint。適用於Java SDK 3.12.0以下版本。
// DefaultProfile.addEndpoint("",regionId, "Sts", endpoint);
// 構造default profile。
IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
// 構造client。
DefaultAcsClient client = new DefaultAcsClient(profile);
final AssumeRoleRequest request = new AssumeRoleRequest();
// 適用於Java SDK 3.12.0及以上版本。
request.setSysMethod(MethodType.POST);
// 適用於Java SDK 3.12.0以下版本。
// request.setMethod(MethodType.POST);
request.setRoleArn(roleArn);
request.setRoleSessionName(roleSessionName);
request.setPolicy(policy);
request.setDurationSeconds(durationSeconds);
final AssumeRoleResponse response = client.getAcsResponse(request);
System.out.println("Expiration: " + response.getCredentials().getExpiration());
System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId());
System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
System.out.println("Security Token: " + response.getCredentials().getSecurityToken());
System.out.println("RequestId: " + response.getRequestId());
} catch (ClientException e) {
System.out.println("Failed:");
System.out.println("Error code: " + e.getErrCode());
System.out.println("Error message: " + e.getErrMsg());
System.out.println("RequestId: " + e.getRequestId());
}
}
}
Python
# -*- coding: utf-8 -*-
from aliyunsdkcore import client
from aliyunsdkcore.request import CommonRequest
import json
import oss2
import os
# 從環境變數中擷取步驟1.1產生的RAM使用者的存取金鑰(AccessKey ID和AccessKey Secret)。
access_key_id = os.getenv("ACCESS_KEY_ID")
access_key_secret = os.getenv("ACCESS_KEY_SECRET")
# 從環境變數中擷取步驟1.3產生的RAM角色的RamRoleArn。
role_arn = os.getenv("RAM_ROLE_ARN")
# 建立權限原則。
clt = client.AcsClient(access_key_id, access_key_secret, 'cn-hangzhou')
request = CommonRequest(product="Sts", version='2015-04-01', action_name='AssumeRole')
request.set_method('POST')
request.set_protocol_type('https')
request.add_query_param('RoleArn', role_arn)
# 指定自訂角色會話名稱,用來區分不同的令牌,例如填寫為sessiontest。
request.add_query_param('RoleSessionName', 'sessiontest')
# 指定STS臨時訪問憑證到期時間為3600秒。
request.add_query_param('DurationSeconds', '3600')
request.set_accept_format('JSON')
body = clt.do_action_with_exception(request)
# 使用RAM使用者的AccessKey ID和AccessKey Secret向STS申請臨時訪問憑證。
token = json.loads(oss2.to_unicode(body))
# 列印STS返回的臨時存取金鑰(AccessKey ID和AccessKey Secret)、安全性權杖(SecurityToken)以及臨時訪問憑證到期時間(Expiration)。
print('AccessKeyId: ' + token['Credentials']['AccessKeyId'])
print('AccessKeySecret: ' + token['Credentials']['AccessKeySecret'])
print('SecurityToken: ' + token['Credentials']['SecurityToken'])
print('Expiration: ' + token['Credentials']['Expiration'])
Node.js
const { STS } = require('ali-oss');
const express = require("express");
const app = express();
app.get('/sts', (req, res) => {
let sts = new STS({
// 從環境變數中擷取步驟1.1產生的RAM使用者的存取金鑰(AccessKey ID和AccessKey Secret)。
accessKeyId : process.env.ACCESS_KEY_ID,
accessKeySecret : process.env.ACCESS_KEY_SECRET
});
// process.env.RAM_ROLE_ARN為從環境變數中擷取步驟1.3產生的RAM角色的RamRoleArn。
// policy填寫自訂權限原則,用於進一步限制STS臨時訪問憑證的許可權。如果不指定Policy,則返回的STS臨時訪問憑證預設擁有指定角色的所有許可權。
// 臨時訪問憑證最後獲得的許可權是步驟4設定的角色許可權和該Policy設定許可權的交集。
// expiration用於設定臨時訪問憑證有效時間單位為秒,最小值為900,最大值以當前角色設定的最大會話時間為準。本樣本指定有效時間為3600秒。
// sessionName用於自訂角色會話名稱,用來區分不同的令牌,例如填寫為sessiontest。
sts.assumeRole('process.env.RAM_ROLE_ARN', ``, '3600', 'sessiontest').then((result) => {
console.log(result);
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Allow-METHOD', 'GET');
res.json({
AccessKeyId: result.credentials.AccessKeyId,
AccessKeySecret: result.credentials.AccessKeySecret,
SecurityToken: result.credentials.SecurityToken,
Expiration: result.credentials.Expiration
});
}).catch((err) => {
console.log(err);
res.status(400).json(err.message);
});
});
app.listen(8000,()=>{
console.log("server listen on:8000")
})
Go
package main
import (
"fmt"
"os"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
sts20150401 "github.com/alibabacloud-go/sts-20150401/v2/client"
util "github.com/alibabacloud-go/tea-utils/v2/service"
"github.com/alibabacloud-go/tea/tea"
)
func main() {
// 從環境變數中擷取步驟1.1產生的RAM使用者的存取金鑰(AccessKey ID和AccessKey Secret)。
accessKeyId := os.Getenv("ACCESS_KEY_ID")
accessKeySecret := os.Getenv("ACCESS_KEY_SECRET")
// 從環境變數中擷取步驟1.3產生的RAM角色的RamRoleArn。
roleArn := os.Getenv("RAM_ROLE_ARN")
// 建立權限原則用戶端。
config := &openapi.Config{
// 必填,步驟1.1擷取到的 AccessKey ID。
AccessKeyId: tea.String(accessKeyId),
// 必填,步驟1.1擷取到的 AccessKey Secret。
AccessKeySecret: tea.String(accessKeySecret),
}
// Endpoint 請參考 https://api.aliyun.com/product/Sts
config.Endpoint = tea.String("sts.cn-hangzhou.aliyuncs.com")
client, err := sts20150401.NewClient(config)
if err != nil {
fmt.Printf("Failed to create client: %v\n", err)
return
}
// 使用RAM使用者的AccessKey ID和AccessKey Secret向STS申請臨時訪問憑證。
request := &sts20150401.AssumeRoleRequest{
// 指定STS臨時訪問憑證到期時間為3600秒。
DurationSeconds: tea.Int64(3600),
// 從環境變數中擷取步驟1.3產生的RAM角色的RamRoleArn。
RoleArn: tea.String(roleArn),
// 指定自訂角色會話名稱,這裡使用和第一段代碼一致的 examplename
RoleSessionName: tea.String("examplename"),
}
response, err := client.AssumeRoleWithOptions(request, &util.RuntimeOptions{})
if err != nil {
fmt.Printf("Failed to assume role: %v\n", err)
return
}
// 列印STS返回的臨時存取金鑰(AccessKey ID和AccessKey Secret)、安全性權杖(SecurityToken)以及臨時訪問憑證到期時間(Expiration)。
credentials := response.Body.Credentials
fmt.Println("AccessKeyId: " + tea.StringValue(credentials.AccessKeyId))
fmt.Println("AccessKeySecret: " + tea.StringValue(credentials.AccessKeySecret))
fmt.Println("SecurityToken: " + tea.StringValue(credentials.SecurityToken))
fmt.Println("Expiration: " + tea.StringValue(credentials.Expiration))
}
php
<?php
require __DIR__ . '/vendor/autoload.php';
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Sts\Sts;
// 從環境變數中擷取步驟1.1產生的RAM使用者的存取金鑰(AccessKey ID和AccessKey Secret)。
$accessKeyId = getenv("ACCESS_KEY_ID");
$accessKeySecret = getenv("ACCESS_KEY_SECRET");
// 從環境變數中擷取步驟1.3產生的RAM角色的RamRoleArn。
$roleArn = getenv("RAM_ROLE_ARN");
// 初始化阿里雲用戶端。
AlibabaCloud::accessKeyClient($accessKeyId, $accessKeySecret)
->regionId('cn-hangzhou')
->asDefaultClient();
try {
// 建立STS請求。
$result = Sts::v20150401()
->assumeRole()
// 設定角色ARN。
->withRoleArn($roleArn)
// 指定自訂角色會話名稱,用來區分不同的令牌。
->withRoleSessionName('sessiontest')
// 指定STS臨時訪問憑證到期時間為3600秒。
->withDurationSeconds(3600)
->request();
// 擷取響應中的憑證資訊。
$credentials = $result['Credentials'];
// 列印STS返回的臨時存取金鑰(AccessKey ID和AccessKey Secret)、安全性權杖(SecurityToken)以及臨時訪問憑證到期時間(Expiration)。
echo 'AccessKeyId: ' . $credentials['AccessKeyId'] . PHP_EOL;
echo 'AccessKeySecret: ' . $credentials['AccessKeySecret'] . PHP_EOL;
echo 'SecurityToken: ' . $credentials['SecurityToken'] . PHP_EOL;
echo 'Expiration: ' . $credentials['Expiration'] . PHP_EOL;
} catch (ClientException $e) {
// 處理用戶端異常。
echo $e->getErrorMessage() . PHP_EOL;
} catch (ServerException $e) {
// 處理服務端異常。
echo $e->getErrorMessage() . PHP_EOL;
}
Ruby
require 'sinatra'
require 'base64'
require 'open-uri'
require 'cgi'
require 'openssl'
require 'json'
require 'sinatra/reloader'
require 'sinatra/content_for'
require 'aliyunsdkcore'
# 設定public檔案夾路徑為當前檔案夾下的templates檔案夾。
set :public_folder, File.dirname(__FILE__) + '/templates'
def get_sts_token_for_oss_upload()
client = RPCClient.new(
# 從環境變數中擷取步驟1.1產生的RAM使用者的存取金鑰(AccessKey ID和AccessKey Secret)。
access_key_id: ENV['ACCESS_KEY_ID'],
access_key_secret: ENV['ACCESS_KEY_SECRET'],
endpoint: 'https://sts.cn-hangzhou.aliyuncs.com',
api_version: '2015-04-01'
)
response = client.request(
action: 'AssumeRole',
params: {
# 從環境變數中擷取步驟1.3產生的RAM角色的RamRoleArn。
"RoleArn": ENV['RAM_ROLE_ARN'],
# 指定STS臨時訪問憑證到期時間為3600秒。
"DurationSeconds": 3600,
# sessionName用於自訂角色會話名稱,用來區分不同的令牌,例如填寫為sessiontest。
"RoleSessionName": "sessiontest"
},
opts: {
method: 'POST',
format_params: true
}
)
end
if ARGV.length == 1
$server_port = ARGV[0]
elsif ARGV.length == 2
$server_ip = ARGV[0]
$server_port = ARGV[1]
end
$server_ip = "0.0.0.0"
$server_port = 8000
puts "App server is running on: http://#{$server_ip}:#{$server_port}"
set :bind, $server_ip
set :port, $server_port
get '/get_sts_token_for_oss_upload' do
token = get_sts_token_for_oss_upload()
response = {
"AccessKeyId" => token["Credentials"]["AccessKeyId"],
"AccessKeySecret" => token["Credentials"]["AccessKeySecret"],
"SecurityToken" => token["Credentials"]["SecurityToken"],
"Expiration" => token["Credentials"]["Expiration"]
}
response.to_json
end
get '/*' do
puts "********************* GET "
send_file File.join(settings.public_folder, 'index.html')
end
已擷取到STS臨時訪問憑證,詳情如下所示:
說明一個阿里雲帳號及該帳號下的RAM使用者、RAM角色,調用STS服務擷取臨時訪問憑證最多100次/秒。在並發數較大的情況下,建議在有效期間內複用臨時訪問憑證。
STS臨時訪問憑證的有效時間採用UTC(國際標準時間)格式。UTC時間與北京時間有8小時時差,為正常情況。例如:臨時訪問憑證到期時間是2024-04-18T11:33:40Z,說明臨時訪問憑證將在北京時間2024年4月18日19時33分40秒之前到期。
{ "AccessKeyId": "STS.NTP*******************oU35V", "AccessKeySecret": "3dZnC*********************************C34hwJuaPu4", "SecurityToken": "CAISv************************************************************************************************************************************CAA", "Expiration": "2024-**-*****:**:50Z" }
若您需要對RAM角色許可權進行更細粒度的配置,可參考以下內容。
如果您希望臨時訪問憑證在獲得角色擁有的許可權後,進一步限制許可權範圍,例如角色被授予了上傳檔案到examplebucket的許可權,您需要限制臨時訪問憑證只能向該Bucket下的某個目錄上傳檔案,您可以通過參考以下樣本設定policy。
// 以下Policy用於限制僅允許使用臨時訪問憑證向examplebucket下的src目錄上傳檔案。 // 臨時訪問憑證最後獲得的許可權是步驟4設定的角色許可權和該Policy設定許可權的交集,即僅允許將檔案上傳至examplebucket下的src目錄。 String policy = "{\n" + " \"Version\": \"1\", \n" + " \"Statement\": [\n" + " {\n" + " \"Action\": [\n" + " \"oss:PutObject\"\n" + " ], \n" + " \"Resource\": [\n" + " \"acs:oss:*:*:examplebucket/src/*\" \n" + " ], \n" + " \"Effect\": \"Allow\"\n" + " }\n" + " ]\n" + "}";
步驟二:企業B使用臨時訪問憑證上傳檔案到OSS
以下樣本展示了如何在臨時訪問憑證有效期間(Expiration)到期之前,使用臨時訪問憑證上傳檔案至OSS。關於SDK的安裝,以及其他程式設計語言使用臨時訪問憑證將檔案上傳至Object Storage Service的程式碼範例,請參見SDK參考。
Java
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyuncs.exceptions.ClientException;
import java.io.File;
public class Demo {
public static void main(String[] args) throws ClientException {
// OSS訪問網域名稱。以華東1(杭州)地區為例,填寫為https://oss-cn-hangzhou.aliyuncs.com。其它Region請按實際情況填寫。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 從環境變數中擷取步驟1.5產生的臨時存取金鑰AccessKey ID和AccessKey Secret,非阿里雲帳號AccessKey ID和AccessKey Secret。
String accessKeyId = System.getenv("ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ACCESS_KEY_SECRET");
// 從環境變數中擷取步驟1.5產生的安全性權杖SecurityToken。
String securityToken = System.getenv("STS_Token");
// 建立OSSClient執行個體。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
// 將本地檔案exampletest.txt上傳至examplebucket。
PutObjectRequest putObjectRequest = new PutObjectRequest("examplebucket", "exampletest.txt", new File("D:\\localpath\\exampletest.txt"));
// ObjectMetadata metadata = new ObjectMetadata();
// 上傳檔案時設定儲存類型。
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
// 上傳檔案時設定讀寫權限ACL。
// metadata.setObjectAcl(CannedAccessControlList.Private);
// putObjectRequest.setMetadata(metadata);
try {
// 上傳檔案。
ossClient.putObject(putObjectRequest);
} 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());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
Python
# -*- coding: utf-8 -*-
import oss2
# yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
endpoint = 'https://oss-cn-hangzhou.aliyuncs.com'
# 填寫步驟1.5產生的臨時存取金鑰AccessKey ID和AccessKey Secret,非阿里雲帳號AccessKey ID和AccessKey Secret。
sts_access_key_id = 'yourAccessKeyId'
sts_access_key_secret = 'yourAccessKeySecret'
# 填寫Bucket名稱。
bucket_name = 'examplebucket'
# 填寫Object完整路徑和字串。Object完整路徑中不能包含Bucket名稱。
object_name = 'examplebt.txt'
# 填寫步驟1.5產生的STS安全性權杖(SecurityToken)。
security_token = 'yourSecurityToken'
# 使用臨時訪問憑證中的認證資訊初始化StsAuth執行個體。
auth = oss2.StsAuth(sts_access_key_id,
sts_access_key_secret,
security_token)
# 使用StsAuth執行個體初始化儲存空間。
bucket = oss2.Bucket(auth, endpoint, bucket_name)
# 上傳Object。
result = bucket.put_object(object_name, "hello world")
print(result.status)
Node.js
此步驟中的樣本需要依賴axios,請在運行前下載。
const axios = require("axios");
const OSS = require("ali-oss");
// 在用戶端使用臨時訪問憑證初始化OSS用戶端,用於臨時授權訪問OSS資源。
const getToken = async () => {
// 設定用戶端請求訪問憑證的地址。
await axios.get("http://localhost:8000/sts").then((token) => {
const client = new OSS({
// yourRegion填寫Bucket所在地區。以華東1(杭州)為例,yourRegion填寫為oss-cn-hangzhou。
region: 'oss-cn-hangzhou',
// 填寫步驟1.5產生的臨時存取金鑰AccessKey ID和AccessKey Secret,非阿里雲帳號AccessKey ID和AccessKey Secret。
accessKeyId: token.data.AccessKeyId,
accessKeySecret: token.data.AccessKeySecret,
// 填寫步驟1.5產生的STS安全性權杖(SecurityToken)。
stsToken: token.data.SecurityToken,
authorizationV4: true,
// 填寫Bucket名稱。
bucket: "examplebucket",
// 重新整理臨時訪問憑證。
refreshSTSToken: async () => {
const refreshToken = await axios.get("http://localhost:8000/sts");
return {
accessKeyId: refreshToken.AccessKeyId,
accessKeySecret: refreshToken.AccessKeySecret,
stsToken: refreshToken.SecurityToken,
};
},
});
// 使用臨時訪問憑證上傳檔案。
// 填寫不包含Bucket名稱在內的Object的完整路徑,例如exampleobject.jpg。
// 填寫本地檔案的完整路徑,例如D:\\example.jpg。
client.put('exampleobject.jpg', 'D:\\example.jpg').then((res)=>{console.log(res)}).catch(e=>console.log(e))
});
};
getToken()
Go
package main
import (
"fmt"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"os"
)
func main() {
// 從環境變數中擷取步驟1.5產生的臨時訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID、OSS_ACCESS_KEY_SECRET、OSS_SESSION_TOKEN。
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)
}
// 填寫Bucket名稱,例如examplebucket。
bucketName := "examplebucket"
// 填寫Object的完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
objectName := "exampledir/exampleobject.txt"
// 填寫本地檔案的完整路徑,例如D:\\localpath\\examplefile.txt。
filepath := "D:\\localpath\\examplefile.txt"
bucket,err := client.Bucket(bucketName)
// 通過STS授權第三方上傳檔案。
err = bucket.PutObjectFromFile(objectName,filepath)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
fmt.Println("upload success")
}
php
<?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\OssClient;
use OSS\Core\OssException;
// 填寫步驟1.5產生的臨時存取金鑰AccessKey ID和AccessKey Secret,非阿里雲帳號AccessKey ID和AccessKey Secret。
$stsAccessKeyId = "yourAccessKeyId";
$stsAccessKeySecret = "yourAccessKeySecret";
// 填寫步驟1.5產生的STS安全性權杖(SecurityToken)。
$securityToken = "yourSecurityToken";
// yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 填寫Bucket名稱。
$bucket = "examplebucket";
// 填寫不包含Bucket名稱在內的Object完整路徑,這裡作為上傳到OSS後的檔案名稱。
$object = "examplebt.txt";
// 填寫本地要上傳的檔案的完整路徑。
$localFilePath = "/path/to/your/local/file.txt";
try {
// 使用臨時訪問憑證建立OssClient執行個體。
$ossClient = new OssClient($stsAccessKeyId, $stsAccessKeySecret, $endpoint, false, $securityToken);
// 上傳檔案到OSS。
$result = $ossClient->uploadFile($bucket, $object, $localFilePath);
// 輸出上傳結果。
printf("檔案上傳成功,ETag: %s\n", $result['etag']);
} catch (OssException $e) {
// 處理異常。
printf("檔案上傳失敗,錯誤資訊: %s\n", $e->getMessage());
}
Ruby
require 'aliyun/sts'
require 'aliyun/oss'
client = Aliyun::OSS::Client.new(
# Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
endpoint: 'https://oss-cn-hangzhou.aliyuncs.com',
# 填寫步驟1.5產生的臨時存取金鑰AccessKey ID和AccessKey Secret,非阿里雲帳號AccessKey ID和AccessKey Secret。
access_key_id: 'token.access_key_id',
access_key_secret: 'token.access_key_secret',
# 填寫步驟1.5產生的STS安全性權杖(SecurityToken)。
sts_token: 'token.security_token'
)
# 填寫Bucket名稱,例如examplebucket。
bucket = client.get_bucket('examplebucket')
# 上傳檔案。
bucket.put_object('exampleobject.txt', :file => 'D:\test.txt')
常見問題
報錯You are not authorized to do this action. You should be authorized by RAM.如何處理?
報錯The Min/Max value of DurationSeconds is 15min/1hr.如何處理?
報錯The security token you provided is invalid.如何處理?
報錯The OSS Access Key Id you provided does not exist in our records.如何處理?
報錯AccessDenied : Anonymous access is forbidden for this operation.如何處理?
報錯NoSuchBucket如何處理?
通過臨時訪問憑證操作OSS資源時報錯You have no right to access this object because of bucket acl.如何處理?
通過臨時訪問憑證操作OSS資源時報錯Access denied by authorizer's policy.如何處理?
報錯The bucket you are attempting to access must be addressed using the specified endpoint.如何處理?
是否支援同時擷取多個臨時訪問憑證?
報錯時間格式不正確如何處理?
返回0003-0000301怎麼處理?
相關文檔
如果您希望從服務端擷取STS臨時訪問憑證後,通過用戶端上傳檔案,且上傳檔案時需要限制上傳的檔案大小、上傳的檔案類型、上傳到Bucket的具體路徑等,請參見用戶端直傳。
通過STS臨時訪問憑證授權上傳檔案到OSS後,您可以通過簽名URL的方式將檔案分享給第三方使用者進行預覽或者下載。具體操作,請參見使用預簽名URL下載檔案。