全部產品
Search
文件中心

Object Storage Service:使用STS臨時訪問憑證訪問OSS

更新時間:May 27, 2025

通過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使用者

  1. 登入RAM控制台

  2. 在左側導覽列,選擇身份管理>使用者,單擊已建立RAM使用者右側對應的添加权限

  3. 新增授權頁面,選擇AliyunSTSAssumeRoleAccess系統策略。

    說明

    授予RAM使用者調用STS服務AssumeRole介面的固定許可權是AliyunSTSAssumeRoleAccess,與後續擷取臨時訪問憑證以及通過臨時訪問憑證發起OSS請求要求的權限無關。

    image

  4. 單擊確認新增授權

3. 建立RAM角色

使用阿里雲主帳號或擁有存取控制(RAM)系統管理權限的RAM帳號建立RAM角色用於定義RAM角色被扮演時,可以獲得OSS服務的哪些存取權限。

  1. 登入RAM控制台

  2. 在左側導覽列,選擇身份管理>角色

  3. 角色頁面,單擊建立角色

  4. 建立角色頁面,選擇信任主體類型雲帳號,然後選擇信任主體名稱當前雲帳號,單擊確定

    image

  5. 建立角色對話方塊,輸入角色名稱,然後單擊確定

  6. 單擊ARN右側的複製,儲存角色的ARN。

    image

4. 為RAM角色授予上傳檔案的許可權

建立完RAM角色後,使用阿里雲主帳號或擁有存取控制(RAM)系統管理權限的RAM帳號為RAM角色附加一個或多個權限原則,明確RAM角色在被扮演時所能擁有的OSS資源存取權限。例如,如果希望RAM使用者在扮演該角色後只能向OSS指定Bucket上傳檔案,則需要為角色添加寫入許可權的策略。

  1. 建立上傳檔案的自訂權限原則。

    1. 登入RAM控制台

    2. 在左側導覽列,選擇权限管理>权限策略

    3. 权限策略頁面,單擊创建权限策略

    4. 创建权限策略頁面,單擊指令碼編輯,然後在策略文檔輸入框中賦予角色上傳檔案到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說明

    5. 策略配置完成後,請單擊確定按鈕,然後在建立權限原則彈出框中填寫策略名稱稱(例如RamTestPolicy),確認資訊無誤後再次單擊確定

  2. 為RAM角色RamOssTest授予自訂權限原則。

    1. 登入RAM控制台

    2. 在左側導覽列,選擇身份管理 > 角色

    3. 角色頁面,找到目標RAM角色RamOssTest

    4. 單擊RAM角色RamOssTest右側的新增授權

    5. 新增授權頁面的權限原則模組中,選擇策略類型為自訂策略,隨後在策略列表中選取已建立的自訂權限原則RamTestPolicy

    6. 單擊確認新增授權

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 = "127.0.0.1"  #如果需要監聽其他地址如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.****************",
      "AccessKeySecret": "3dZn*******************************************",
      "SecurityToken": "CAIS*****************************************************************************************************************************************",
      "Expiration": "2024-**-*****:**:50Z"
    }
  • 若您需要對臨時存取權限進行更細粒度的配置,可參考以下內容。

    如果您希望臨時訪問憑證在獲得角色擁有的許可權後,進一步限制許可權範圍,例如角色被授予了上傳檔案到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安裝指南及各程式設計語言使用臨時訪問憑證操作OSS(如檔案上傳、下載等)的程式碼範例,請參見SDK參考

Java

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;

import java.io.File;

public class Demo {

    public static void main(String[] args) throws Exception {
        // 請填寫步驟1.5產生的臨時存取金鑰AccessKey ID、AccessKey Secret和SecurityToken,而非RAM使用者的身份憑證資訊
        // 請注意區分STS服務擷取的AccessKey ID是以STS開頭
        String accessKeyId = "yourSTSAccessKeyID";
        String accessKeySecret = "yourSTSAccessKeySecret";
        // 填寫擷取的STS安全性權杖(SecurityToken)。
        String stsToken= "yourSecurityToken";

        // 使用DefaultCredentialProvider方法直接設定AK和SK
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret, stsToken);
        // 使用credentialsProvider初始化用戶端
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        // 顯式聲明使用 V4 簽名演算法
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        // 建立OSSClient執行個體。
        // 當OSSClient執行個體不再使用時,調用shutdown方法以釋放資源。
        OSS ossClient = OSSClientBuilder.create()
                 // 請設定目的OSS訪問網域名稱  例如杭州地區:https://oss-cn-hangzhou.aliyuncs.com
                .endpoint("endpoint")
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                // 請設定為目標Bucket所處region  例如杭州地區:cn-hangzhou
                .region("region")
                .build();

        try {

            // 建立PutObjectRequest對象,將本地檔案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());
            // metadata.setObjectAcl(CannedAccessControlList.Private);
            // putObjectRequest.setMetadata(metadata);

            // 上傳檔案
            PutObjectResult result = 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());
        } 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();
            }
        }
    }
}

Python

Python SDK目前提供V2和V1兩個版本。V2在V1基礎上全面重構,簡化了身分識別驗證、請求重試、錯誤處理等底層操作,提供更靈活的參數配置和新的進階介面。請根據您的實際使用需求,參考如下樣本。

V2樣本

import alibabacloud_oss_v2 as oss

def main():
    # 請填寫步驟1.5產生的臨時存取金鑰AccessKey ID、AccessKey Secret和SecurityToken,而非RAM使用者的身份憑證資訊
    # 請注意區分STS服務擷取的AccessKey ID是以STS開頭
    sts_access_key_id = 'yourSTSAccessKeyID'
    sts_access_key_secret = 'yourSTSAccessKeySecret'
    # 填寫擷取的STS安全性權杖(SecurityToken)
    sts_security_token = 'yourSecurityToken'
    
    # 建立靜態憑證提供者,顯式設定臨時存取金鑰AccessKey ID和AccessKey Secret,以及STS安全性權杖
    credentials_provider = oss.credentials.StaticCredentialsProvider(
        access_key_id=sts_access_key_id,
        access_key_secret=sts_access_key_secret,
        security_token=sts_security_token,
    )

    # 載入SDK的預設配置,並設定憑證提供者
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider

    # 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou
    cfg.region = 'cn-hangzhou'

    # 使用配置好的資訊建立OSS用戶端
    client = oss.Client(cfg)

    # 待上傳本地檔案路徑  例如 D:\\localpath\\exampletest.txt
    local_file_path = 'D:\\localpath\\exampletest.txt'
    with open(local_file_path, 'rb') as file:
        data = file.read()

    # 執行上傳對象的請求,將本地檔案exampletest.txt上傳至examplebucket,指定儲存空間名稱、對象名稱和上傳檔案
    result = client.put_object(oss.PutObjectRequest(
        # Bucket名稱
        bucket='examplebucket',
        # 上傳到Bucket中的對象名稱
        key='exampletest.txt',
        body=data,
    ))

     # 輸出請求的結果狀態代碼、請求ID、內容MD5、ETag、CRC64校正碼和版本ID,用於檢查請求是否成功
    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' content md5: {result.content_md5},'
          f' etag: {result.etag},'
          f' hash crc64: {result.hash_crc64},'
          f' version id: {result.version_id},'
    )


# 當此指令碼被直接運行時,調用main函數
if __name__ == "__main__":
    main()  # 指令碼入口,當檔案被直接運行時調用main函數

V1樣本

# -*- 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)

Go

Go SDK目前提供V2和V1兩個版本。V2在V1基礎上全面重構,簡化了身分識別驗證、請求重試、錯誤處理等底層操作,提供更靈活的參數配置和新的進階介面。請根據您的實際使用需求,參考如下樣本。

V2樣本

package main

import (
	"context"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

func main() {
	// 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou
	region := "cn-hangzhou"

	// 請填寫步驟1.5產生的臨時存取金鑰AccessKey ID、AccessKey Secret和SecurityToken,而非RAM使用者的身份憑證資訊
        // 請注意區分STS服務擷取的AccessKey ID是以STS開頭
	accessKeyID := "yourSTSAccessKeyID"
	accessKeySecret := "yourSTSAccessKeySecret"
	// 填寫擷取的STS安全性權杖(SecurityToken)
	stsToken := "yourSecurityToken"

	// 使用NewStaticCredentialsProvider方法直接設定AK、SK和STS Token
	provider := credentials.NewStaticCredentialsProvider(accessKeyID, accessKeySecret, stsToken)

	// 載入預設配置並設定憑證提供者和地區
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(provider).
		WithRegion(region)

	// 建立OSS用戶端
	client := oss.NewClient(cfg)

	// 填寫要上傳的本地檔案路徑和檔案名稱,例如 D:\\localpath\\exampletest.txt
	localFile := "D:\\localpath\\exampletest.txt"

	// 建立上傳對象的請求
	putRequest := &oss.PutObjectRequest{
		Bucket:       oss.Ptr("examplebucket"),      // Bucket名稱
		Key:          oss.Ptr("exampletest.txt"),    // 上傳到Bucket中的對象名稱
		StorageClass: oss.StorageClassStandard, // 指定對象的儲存類型為標準儲存
		Acl:          oss.ObjectACLPrivate,     // 指定對象的存取權限為私人訪問
		Metadata: map[string]string{
			"yourMetadataKey1": "yourMetadataValue1", // 設定對象的中繼資料
		},
	}

	// 執行上傳對象的請求,將本地檔案exampletest.txt上傳至examplebucket
	result, err := client.PutObjectFromFile(context.TODO(), putRequest, localFile)
	if err != nil {
		log.Fatalf("failed to put object from file %v", err)
	}

	// 列印上傳對象的結果
	log.Printf("put object from file result:%#v\n", result)
	
}

V1樣本

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")
}

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.data.AccessKeyId,
          accessKeySecret: refreshToken.data.AccessKeySecret,
          stsToken: refreshToken.data.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()

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\Credentials\StaticCredentialsProvider;
use OSS\OssClient;
use OSS\Core\OssException;

try {
    // 請填寫步驟1.5產生的臨時存取金鑰AccessKey ID、AccessKey Secret和SecurityToken,而非RAM使用者的身份憑證資訊
    // 請注意區分STS服務擷取的AccessKey ID是以STS開頭
    $accessKeyId = 'yourSTSAccessKeyID';
    $accessKeySecret = 'yourSTSAccessKeySecret';
    // 填寫擷取的STS安全性權杖(SecurityToken)
    $securityToken = 'yourSecurityToken';

    // 使用StaticCredentialsProvider類建立憑證提供者
    $provider = new StaticCredentialsProvider($accessKeyId, $accessKeySecret, $securityToken);

    // 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com
    $endpoint = "https://oss-cn-hangzhou.aliyuncs.com";

    // 填寫Bucket名稱,例如examplebucket。
    $bucket= "examplebucket";
    // 填寫上傳到Bucket中的對象名稱
    $object = "exampletest.txt";
    // 填寫待上傳本地檔案路徑,例如 D:\\localpath\\exampletest.txt
    $localFilePath = "D:\\localpath\\exampletest.txt";

    // 上傳時可以設定相關的headers,例如設定存取權限為private、自訂中繼資料等
    $options = array(
        OssClient::OSS_HEADERS => array(
            'x-oss-object-acl' => 'private',
            'x-oss-meta-info' => 'yourinfo'
        ),
    );

    $config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
        "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
        // 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou
        "region" => "cn-hangzhou"
    );
    
    // 使用配置好的資訊建立OSS用戶端
    $ossClient = new OssClient($config);
    
     // 發送請求 將本地檔案exampletest.txt上傳至examplebucket
    $ossClient->putObject($bucket, $object, $localFilePath, $options);
} catch (OssException $e) {
    printf($e->getMessage() . "\n");
    return;
}

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.如何處理?

步驟1.5中使用RAM使用者扮演RAM角色擷取臨時訪問憑證時,必須使用RAM使用者的存取金鑰(AccessKey ID和AccessKey Secret),不能使用阿里雲帳號的存取金鑰發起請求。

報錯The Min/Max value of DurationSeconds is 15min/1hr.如何處理?

報錯原因是設定的臨時訪問憑證有效期間超出允許的時間範圍。請遵循以下原則設定有效期間:

  • 如果沒有自訂角色最大會話時間,則當前角色會話時間預設值為3600秒。此時,通過durationSeconds設定的臨時訪問憑證有效時間允許的最小值為900秒,最大值為3600秒。

  • 如果自訂了角色最大會話時間,則通過durationSeconds設定的臨時訪問憑證有效時間的最小值為900秒,最大值以角色最大會話時間為準。角色會話時間允許設定的取值範圍為3600秒~43200秒。

您可以通過RAM控制台查看角色最大會話時間。具體步驟,請參見查看RAM角色

報錯The security token you provided is invalid.如何處理?

請確保完整填寫步驟1.5擷取到的SecurityToken。

報錯The OSS Access Key Id you provided does not exist in our records.如何處理?

臨時訪問憑證已到期,到期後自動失效。請使用臨時存取金鑰(AccessKeyId和AccessKeySecret)向App伺服器申請新的臨時訪問憑證。具體操作,請參見步驟1.5

報錯AccessDenied : Anonymous access is forbidden for this operation.如何處理?

通過步驟1.5擷取臨時訪問憑證時,您需要使用填寫步驟1.1產生的RAM使用者存取金鑰AccessKey ID和AccessKey Secret,非阿里雲帳號AccessKey ID和AccessKey Secret。

報錯NoSuchBucket如何處理?

出現該報錯的原因是指定的Bucket不存在。請檢查並配置正確的Bucket名稱。

通過臨時訪問憑證操作OSS資源時報錯You have no right to access this object because of bucket acl.如何處理?

出現該報錯通常是Policy設定錯誤。關於Policy中涉及各元素的填寫要求,請參見RAM Policy。如果您需要擷取具有分區上傳、追加上傳等許可權的臨時訪問憑證,您需要通過Policy中的Action元素授予對應許可權。關於OSS Action的更多資訊,請參見OSS Action分類

通過臨時訪問憑證操作OSS資源時報錯Access denied by authorizer's policy.如何處理?

出現該報錯通常是無許可權執行相關操作。申請臨時訪問憑證之前,需要建立用於擷取臨時訪問憑證的RAM角色並完成角色授權(本文檔步驟1.4)。向STS伺服器發起扮演該角色的請求,以擷取臨時訪問憑證時可以通過policy參數進一步限制臨時訪問憑證的許可權(本文檔步驟1.5)。

  • 如果設定policy,則臨時訪問憑證最終的許可權是RAM角色權限原則與policy權限原則的交集。

    • 樣本1

      如下圖所示,A代表RAM角色的許可權,B代表通過policy參數設定的許可權,C代表臨時訪問憑證最終的許可權。

      1.jpg

    • 樣本2

      如下圖所示,A代表RAM角色許可權,B代表通過policy參數設定的許可權,且policy參數設定的許可權是RAM角色許可權的子集。因此,B代表臨時訪問憑證的最終許可權。

      2.jpg

  • 如果不設定policy,則臨時訪問憑證具有與RAM角色相同的權限原則。

報錯The bucket you are attempting to access must be addressed using the specified endpoint.如何處理?

出現該報錯的原因是步驟二中的Endpoint參數填寫錯誤。您需要根據Bucket所在Region填寫對應的Endpoint。關於Region與Endpoint對應關係的說明,請參見OSS地區和訪問網域名稱

是否支援同時擷取多個臨時訪問憑證?

支援。發起一次請求僅返回一個臨時訪問憑證。如果您希望擷取多個臨時訪問憑證,您需要發起多次請求。在有效期間內,您可以同時使用擷取到的多個臨時訪問憑證。

報錯時間格式不正確如何處理?

如果調用時報錯時間格式不正確,可能是由於Timestamp參數中間多餘空格,請排查修改。

請求的時間戳記日期格式按照ISO8601標準表示,並需要使用UTC時間。格式為:YYYY-MM-DDThh:mm:ssZ。例如,2014-05-26T12:00:00Z(為北京時間2014年5月26日20點0分0秒)。

返回0003-0000301怎麼處理?

返回0003-0000301原因是臨時訪問憑證不具有執行OSS相關操作的許可權,解決方案請參見0003-00000301

相關文檔

  • 如果您希望從服務端擷取STS臨時訪問憑證後,通過用戶端上傳檔案,且上傳檔案時需要限制上傳的檔案大小、上傳的檔案類型、上傳到Bucket的具體路徑等,請參見用戶端直傳

  • 通過STS臨時訪問憑證授權上傳檔案到OSS後,您可以通過簽名URL的方式將檔案分享給第三方使用者進行預覽或者下載。具體操作,請參見使用預簽名URL下載檔案