全部產品
Search
文件中心

Alibaba Cloud SDK:管理訪問憑據

更新時間:Jun 19, 2025

在使用阿里雲SDK調用OpenAPI進行資源操作時,正確配置憑證資訊至關重要。阿里雲Credentials工具提供了一整套便捷功能,支援多種憑證類型,包括預設憑證、AccessKey(AK)以及STS令牌等,以協助您高效擷取和管理訪問憑證。本文將詳細介紹各種類型憑證的配置方法以及如何根據優先順序使用預設憑證。通過本文,您將深入理解如何在阿里雲SDK中配置和維護憑證,從而確保對雲資源的操作既高效又具有高度安全性。

背景資訊

憑據是指使用者證明其身份的一組資訊。使用者在系統中進行登入時,需要提供正確的憑據才能驗證身份。常見的憑據類型有:

  1. 阿里雲主帳號和RAM使用者的永久憑據 AccessKey(簡稱AK)是由AccessKey ID和AccessKey Secret組成的金鑰組。

  2. 阿里雲RAM角色的STS臨時訪問Token,簡稱STS Token。它是可以自訂時效和存取權限的臨時身份憑據,詳情請參見什麼是STS

  3. Bearer Token。它是一種身分識別驗證和授權的令牌類型。

前提條件

  • 使用Credentials工具要求Python版本 >= 3.7。

  • 使用V2.0代系的阿里雲SDK。

安裝Credentials工具

使用pip安裝(推薦),如未安裝pip,請先安裝pip。更多資訊,請參見pip官網pip user guide

pip install alibabacloud_credentials
  • 使用最新發行Credentials依賴包,確保所有憑證支援。

  • 請查看ChangeLog.txt擷取所有發行的版本列表。

Credentials工具配置參數介紹

Credentials工具的配置參數定義在alibabacloud_credentials.models模組的Config類中,憑據類型由必填參數type指定。確定憑據類型後,需根據該憑據類型選擇相應的參數。下表將詳細介紹type的取值範圍及各類憑據類型所支援的參數。其中,表示必填參數,-表示選擇性參數,×表示不支援參數。

說明

未在下表中列出的憑據類型及參數表示不建議繼續使用。

type

access_key

sts

ram_role_arn

ecs_ram_role

oidc_role_arn

credentials_uri

bearer

access_key_id:訪問憑據ID。

×

×

×

×

access_key_secret:訪問憑據密鑰。

×

×

×

×

security_token:STS Token。

×

-

×

×

×

×

role_arn:RAM角色的ARN。

×

×

×

×

×

role_session_name:自訂會話名稱,預設格式為credentials-python-目前時間的時間戳記

×

×

-

×

-

×

×

role_name:RAM角色名稱。

×

×

×

-

×

×

×

disable_imds_v1:是否強制使用加固模式,預設值為false

×

×

×

-

×

×

×

bearer_token:bearer token。

×

×

×

×

×

×

policy:自訂權限原則。

×

×

-

×

-

×

×

role_session_expiration:會話到期時間,預設3600秒。

×

×

-

×

-

×

×

oidc_provider_arn:OIDC供應商ARN。

×

×

×

×

×

×

oidc_token_file_path:OIDC Token檔案路徑。

×

×

×

×

×

×

external_id:角色外部 ID,主要功能是防止混淆代理人問題。更多資訊,請參見使用ExternalId防止混淆代理人問題

×

×

-

×

×

×

×

credentials_uri:憑證的URI。

×

×

×

×

×

×

sts_endpoint:STS的服務存取點,支援VPC服務存取點和公網服務存取點,可選的值請參見服務存取點,預設值為sts.aliyuncs.com

×

×

-

×

-

×

×

timeout:HTTP請求的讀逾時時間,預設值為5000毫秒。

×

×

-

-

-

-

×

connect_timeout:HTTP請求的連線逾時時間,預設值為10000毫秒。

×

×

-

-

-

-

×

初始化憑據用戶端

Credentials工具支援多種方式初始化憑據用戶端,您可根據實際情況選擇合適的方式進行憑據用戶端初始化。

重要
  • 在專案中使用明文AccessKey,容易因代碼倉庫許可權管理不當造成AccessKey泄露,會威脅該帳號下所有資源的安全。建議通過環境變數、設定檔等方式擷取AccessKey。

  • 在初始化憑據用戶端時建議採用單例模式,這不僅可啟用SDK的憑證緩衝功能,還能有效防止因多次調用介面導致的流量控制問題和效能資源的浪費,詳細資料請參見Session類型憑據自動重新整理機制

方式一:使用預設憑據鏈

當您在初始化憑據用戶端不傳入任何參數時,Credentials工具會使用預設憑據鏈方式初始化用戶端。預設憑據的讀取邏輯請參見預設憑據鏈

from alibabacloud_credentials.client import Client as CredClient

# 不指定參數
credentialsClient = CredClient()

credential = credentialsClient.get_credential()
access_key_id = credential.get_access_key_id()
access_key_secret = credential.get_access_key_secret()
security_token = credential.get_security_token()
cred_type = credential.get_type()

介面調用方法

通過預設憑據提供鏈自動建立訪問憑證,並在不使用寫入程式碼AccessKey的情況下成功調用雲產品OpenAPI介面。

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

# Credentials和雲產品SDK都需引入Client,此處為建立別名。
from alibabacloud_credentials.client import Client as CredClient
# 引入阿里雲ECS SDK,此處以ECS產品為例。
from alibabacloud_ecs20140526.client import Client as EcsClient
# 使用ECS DescribeRegions介面發起調用請求。
from alibabacloud_ecs20140526.models import DescribeRegionsRequest
# 引入阿里雲SDK核心包。
from alibabacloud_tea_openapi.models import Config
from alibabacloud_tea_util.models import RuntimeOptions

# 使用預設憑證初始化Credentials Client。
credentialsClient = CredClient()
ecsConfig = Config(credential=credentialsClient)
# 配置雲產品服務接入地址(endpoint)。
ecsConfig.endpoint = 'ecs.cn-hangzhou.aliyuncs.com'
# 使用Credentials Client初始化ECS Client。
ecsClient = EcsClient(ecsConfig)
# 初始化DescribeRegions請求。
request = DescribeRegionsRequest()
# 初始化運行時配置。
runtime_options = RuntimeOptions()
# 調用DescribeRegions介面並獲得響應。
response = ecsClient.describe_regions_with_options(request, runtime_options)
print(response.to_map())

方式二:使用AK

該方式通過設定AK初始化憑據用戶端,如何擷取AK,請參見建立AccessKey

警告

阿里雲主帳號擁有資源的全部許可權,AK一旦泄露,會給系統帶來巨大風險,不建議使用。

推薦使用最小化授權的RAM使用者的AK。

import os
from alibabacloud_credentials.client import Client
from alibabacloud_credentials.models import Config

config = Config(
	type='access_key',
	access_key_id=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID'),
	access_key_secret=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
)
cred = Client(config)

credential = cred.get_credential()
access_key_id = credential.get_access_key_id()
access_key_secret = credential.get_access_key_secret()
security_token = credential.get_security_token()
cred_type = credential.get_type()

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

import os

# Credentials和雲產品SDK都需引入Client,此處為建立別名。
from alibabacloud_credentials.client import Client as CredClient
from alibabacloud_credentials.models import Config as CreConfig
# 引入阿里雲ECS SDK,此處以ECS產品為例。
from alibabacloud_ecs20140526.client import Client as EcsClient
# 使用ECS DescribeRegions介面發起調用請求。
from alibabacloud_ecs20140526.models import DescribeRegionsRequest
from alibabacloud_tea_openapi.models import Config
from alibabacloud_tea_util.models import RuntimeOptions

# 使用AK 初始化Credentials Client。
credentialsConfig = CreConfig(
    # 憑證類型。
    type='access_key',
    # 設定為AccessKey ID值。
    access_key_id=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID'),
    # 設定為AccessKey Secret值。
    access_key_secret=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
)
credentialClient = CredClient(credentialsConfig)

ecsConfig = Config(credential=credentialClient)
# 配置雲產品服務接入地址(endpoint)。
ecsConfig.endpoint = 'ecs.cn-hangzhou.aliyuncs.com'
# 初始化ECS Client。
ecsClient = EcsClient(ecsConfig)

# 初始化DescribeRegions請求。
request = DescribeRegionsRequest()
# 初始化運行時配置。
runtime_options = RuntimeOptions()
# 調用DescribeRegions介面並獲得響應。
response = ecsClient.describe_regions_with_options(request, runtime_options)
print(response.to_map())

方式三:使用STS Token

該方式是通過設定靜態STS Token的方式初始化憑據。如何擷取STS Token,請參見什麼是STS。以下樣本示範如何使用STS Token初始化憑據用戶端(不包含如何擷取到STS Token的過程)。

import os

from alibabacloud_credentials.client import Client
from alibabacloud_credentials.models import Config

config = Config(
    type='sts',
    # 從環境變數中擷取AccessKey ID的值
    access_key_id=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID'),
    # 從環境變數中擷取AccessKeySecret的值
    access_key_secret=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
    # 從環境變數中擷取臨時SecurityToken的值
    security_token=os.environ.get('ALIBABA_CLOUD_SECURITY_TOKEN')
)
credClient = Client(config)

credential = credClient.get_credential()
access_key_id = credential.get_access_key_id()
access_key_secret = credential.get_access_key_secret()
security_token = credential.get_security_token()
cred_type = credential.get_type()

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝Elastic Compute Service SDKSecurity Token Service SDK

import os

from alibabacloud_credentials.client import Client as CredClient
from alibabacloud_credentials.models import Config as CreConfig
from alibabacloud_ecs20140526.client import Client as EcsClient
from alibabacloud_ecs20140526.models import DescribeRegionsRequest
from alibabacloud_sts20150401.client import Client as Sts20150401Client
from alibabacloud_sts20150401.models import AssumeRoleRequest
from alibabacloud_tea_openapi.models import Config
from alibabacloud_tea_util.models import RuntimeOptions

# 從環境變數中擷取RAM使用者ak
config = Config(
    access_key_id=os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'],
    access_key_secret=os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET']
)
config.endpoint = "sts.aliyuncs.com"
stsClient = Sts20150401Client(config)

# 調AssumeRole API的參數
assume_role_request = AssumeRoleRequest(
    # 會話有效時間
    duration_seconds=3600,
    # 要扮演的RAM角色ARN,樣本值:acs:ram::123456789012****:role/adminrole,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定role_arn
    role_arn='<role_arn>',
    # 角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定role_session_name
    role_session_name='<role_session_name>'
)
runtime = RuntimeOptions()
try:
    resp = stsClient.assume_role_with_options(assume_role_request, runtime)
    assumeRoleResponseBodyCredentials = resp.body.credentials

    # 使用STS Token初始化Credentials Client。
    credentialsConfig = CreConfig(
        # 憑證類型。
        type='sts',
        # 設定為AccessKey ID值。
        access_key_id=assumeRoleResponseBodyCredentials.access_key_id,
        # 設定為AccessKey Secret值。
        access_key_secret=assumeRoleResponseBodyCredentials.access_key_secret,
        # 設定為STS Token值。
        security_token=assumeRoleResponseBodyCredentials.security_token
    )
    credentialClient = CredClient(credentialsConfig)
    ecsConfig = Config(credential=credentialClient)
    # 配置雲產品服務接入地址(endpoint)。
    ecsConfig.endpoint = 'ecs.cn-hangzhou.aliyuncs.com'
    # 初始化ECS Client。
    ecsClient = EcsClient(ecsConfig)

    # 初始化DescribeRegions請求。
    request = DescribeRegionsRequest()
    # 初始化運行時配置。
    runtime_options = RuntimeOptions()
    # 調用DescribeRegions介面並獲得響應。
    response = ecsClient.describe_regions_with_options(request, runtime_options)
    print(response.to_map())
except Exception as error:
    # 錯誤 message
    print(error.message)

方式四:使用AK及RamRoleArn

該方式底層實現是STS Token。通過指定RAM角色的ARN(Alibabacloud Resource Name),Credentials工具可以協助開發人員前往STS換取STS Token。您也可以通過為policy賦值來限制RAM角色到一個更小的許可權集合。

import os

from alibabacloud_credentials.client import Client as CredClient
from alibabacloud_credentials.models import Config as CredConfig

credentialsConfig = CredConfig(
    access_key_id=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID'),
    access_key_secret=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
    type='ram_role_arn',
    # 要扮演的RAM角色ARN,樣本值:acs:ram::123456789012****:role/adminrole,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定role_arn
    role_arn='<role_arn>',
    # 角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定role_session_name
    role_session_name='<role_session_name>',
    # 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
    policy='<policy>',
    role_session_expiration=3600
)
credentialsClient = CredClient(credentialsConfig)

credential = credentialsClient.get_credential()
access_key_id = credential.get_access_key_id()
access_key_secret = credential.get_access_key_secret()
security_token = credential.get_security_token()
cred_type = credential.get_type()

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

import os

from alibabacloud_credentials.client import Client as CredClient
from alibabacloud_credentials.models import Config as CredConfig
from alibabacloud_ecs20140526.client import Client as EcsClient
from alibabacloud_ecs20140526.models import DescribeRegionsRequest
from alibabacloud_tea_openapi.models import Config
from alibabacloud_tea_util.models import RuntimeOptions

# 使用RamRoleArn初始化Credentials Client。
credentialsConfig = CredConfig(
    type='ram_role_arn',  # 憑證類型。
    access_key_id=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID'),  # 從環境變數中擷取AccessKey ID。
    access_key_secret=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),  # 從環境變數中擷取AccessKey Secret。
    # 要扮演的RAM角色ARN,樣本值:acs:ram::123456789012****:role/adminrole,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定role_arn
    role_arn='<role_arn>',
    # 角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定role_session_name
    role_session_name='<role_session_name>',
    # 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
    policy='<policy>',
    role_session_expiration=3600  # 會話有效時間
)
credentialsClient = CredClient(credentialsConfig)
ecsConfig = Config(credential=credentialsClient)
# 配置雲產品服務接入地址(endpoint)。
ecsConfig.endpoint = 'ecs.aliyuncs.com'
# 使用Credentials Client初始化ECS Client。
ecsClient = EcsClient(ecsConfig)
# 初始化DescribeRegions請求。
request = DescribeRegionsRequest()
# 初始化運行時配置。
runtime_options = RuntimeOptions()
# 調用DescribeRegions介面並獲得響應。
response = ecsClient.describe_regions_with_options(request, runtime_options)
print(response.to_map())

方式五:使用ECS執行個體RAM角色

ECS和ECI執行個體均支援綁定執行個體RAM角色,運行於執行個體中的程式可通過Credentials工具自動擷取該角色的STS Token,從而完成憑據用戶端的初始化。

Credentials工具將預設採用加固模式(IMDSv2)訪問ECS的中繼資料服務(Meta Data Server),在使用加固模式時若發生異常,將使用普通模式兜底來擷取訪問憑據。您也可以通過設定參數enable_imds_v1或環境變數ALIBABA_CLOUD_IMDSV1_DISABLE,執行不同的異常處理邏輯:

  • 當值為false(預設)時,會使用普通模式繼續擷取訪問憑據。

  • 當值為true時,表示只能使用加固模式擷取訪問憑據,會拋出異常。

服務端是否支援IMDSv2,取決於您在伺服器的配置。

另外,您可以通過配置環境變數ALIBABA_CLOUD_ECS_METADATA_DISABLED=true來關閉ECS中繼資料的憑證訪問。

說明
說明

使用加固模式擷取臨時身份憑證時,alibabacloud_credentials的版本不低於0.3.6

from alibabacloud_credentials.client import Client as CredClient
from alibabacloud_credentials.models import Config as CredConfig

credentialsConfig = CredConfig(
	type='ecs_ram_role',
	# 選填,該ECS角色的角色名稱,不填會自動擷取,但是建議加上以減少請求次數,可以通過環境變數ALIBABA_CLOUD_ECS_METADATA設定role_name
	role_name='<role_name>',
	# 選填,預設值:False。True:表示強制使用加固模式。False:系統將首先嘗試在加固模式下擷取憑據。如果失敗,則會切換到普通模式(IMDSv1)進行嘗試
	# enable_imds_v1=True,
)
credentialsClient = CredClient(credentialsConfig)

credential = credentialsClient.get_credential()
access_key_id = credential.get_access_key_id()
access_key_secret = credential.get_access_key_secret()
security_token = credential.get_security_token()
cred_type = credential.get_type()

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

# Credentials和雲產品SDK都需引入Client,此處為建立別名。
from alibabacloud_credentials.client import Client as CredClient
from alibabacloud_credentials.models import Config as CredConfig
# 引入阿里雲ECS SDK,此處以ECS產品為例。
from alibabacloud_ecs20140526.client import Client as EcsClient
# 使用ECS DescribeRegions介面發起調用請求。
from alibabacloud_ecs20140526.models import DescribeRegionsRequest
# 引入阿里雲SDK核心包。
from alibabacloud_tea_openapi.models import Config
from alibabacloud_tea_util.models import RuntimeOptions

# 使用EcsRamRole初始化Credentials Client。
credentialsConfig = CredConfig(
    type='ecs_ram_role',  # 憑證類型。
    # 選填,該ECS角色的角色名稱,不填會自動擷取,但是建議加上以減少請求次數,可以通過環境變數ALIBABA_CLOUD_ECS_METADATA設定role_name
    role_name='<role_name>'
)
credentialsClient = CredClient(credentialsConfig)
ecsConfig = Config(credential=credentialsClient)
# 配置雲產品服務接入地址(endpoint)。
ecsConfig.endpoint = 'ecs.aliyuncs.com'
# 使用Credentials Client初始化ECS Client。
ecsClient = EcsClient(ecsConfig)

# 初始化DescribeRegions請求。
request = DescribeRegionsRequest()
# 初始化運行時配置。
runtime_options = RuntimeOptions()
# 調用DescribeRegions介面並獲得響應。
response = ecsClient.describe_regions_with_options(request, runtime_options)
print(response.to_map())

方式六:使用OIDCRoleArn

說明

該功能要求alibabacloud_credentials的版本不低於0.3.1。

為了避免影響雲上資源的安全,同時又能讓不可信的應用安全地擷取所需的 STS Token,實現應用層級的許可權最小化,您可以使用RRSA(RAM Roles for Service Account)功能。阿里雲容器叢集會為不同的應用Pod建立和掛載相應的服務賬戶OIDC Token檔案,並將相關配置資訊注入到環境變數中,Credentials工具通過擷取環境變數的配置資訊,調用STS服務的AssumeRoleWithOIDC介面換取綁定角色的STS Token。

注入的環境變數如下:

ALIBABA_CLOUD_ROLE_ARN:RAM角色名稱ARN;

ALIBABA_CLOUD_OIDC_PROVIDER_ARN:OIDC供應商ARN;

ALIBABA_CLOUD_OIDC_TOKEN_FILE:OIDC Token檔案路徑;

from alibabacloud_credentials.client import Client
from alibabacloud_credentials.models import Config

config = Config(
    type='oidc_role_arn',
    # RAM角色名稱ARN,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定role_arn
    role_arn='<role_arn>',
    # OIDC供應商ARN,可以通過環境變數ALIBABA_CLOUD_OIDC_PROVIDER_ARN設定oidc_provider_arn
    oidc_provider_arn='<oidc_provider_arn>',
    # OIDC Token檔案路徑,可以通過環境變數ALIBABA_CLOUD_OIDC_TOKEN_FILE設定oidc_token_file_path
    oidc_token_file_path='<oidc_token_file_path>',
    # 角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定role_session_name
    role_session_name='<role_session_name>',
    # 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
    policy='<policy>',
    # 設定session到期時間
    role_session_expiration=3600
)
cred = Client(config)

credential = cred.get_credential()
access_key_id = credential.get_access_key_id()
access_key_secret = credential.get_access_key_secret()
security_token = credential.get_security_token()
cred_type = credential.get_type()

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

from alibabacloud_credentials.client import Client as CredClient
from alibabacloud_credentials.models import Config as CredConfig
from alibabacloud_ecs20140526.client import Client as EcsClient
from alibabacloud_ecs20140526.models import DescribeRegionsRequest
from alibabacloud_tea_openapi.models import Config
from alibabacloud_tea_util.models import RuntimeOptions

# 使用OIDCRoleArn初始化Credentials Client。
credentialsConfig = CredConfig(
    type='oidc_role_arn',
    # RAM角色名稱ARN,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定role_arn
    role_arn='<role_arn>',
    # OIDC供應商ARN,可以通過環境變數ALIBABA_CLOUD_OIDC_PROVIDER_ARN設定oidc_provider_arn
    oidc_provider_arn='<oidc_provider_arn>',
    # OIDC Token檔案路徑,可以通過環境變數ALIBABA_CLOUD_OIDC_TOKEN_FILE設定oidc_token_file_path
    oidc_token_file_path='<oidc_token_file_path>',
    # 角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定role_session_name
    role_session_name='<role_session_name>',
    # 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
    policy='<policy>',
    # 設定session到期時間
    role_session_expiration=3600
)
credentialsClient = CredClient(credentialsConfig)
ecsConfig = Config(credential=credentialsClient)
# 配置雲產品服務接入地址(endpoint)。
ecsConfig.endpoint = 'ecs.aliyuncs.com'
# 使用Credentials Client初始化ECS Client。
ecsClient = EcsClient(ecsConfig)

# 初始化DescribeRegions請求。
request = DescribeRegionsRequest()
# 初始化運行時配置。
runtime_options = RuntimeOptions()
# 調用DescribeRegions介面並獲得響應。
response = ecsClient.describe_regions_with_options(request, runtime_options)
print(response.to_map())

方式七:使用URI憑據

通過在應用內部封裝STS Token服務並對外提供自訂URI,其他服務僅能通過該URI擷取STS Token,這樣能夠有效降低AK等資訊的暴露風險。Credentials工具支援通過請求該服務的URI來擷取STS Token,從而實現憑據用戶端的初始化。

from alibabacloud_credentials.client import Client
from alibabacloud_credentials.models import Config

config = Config(
    type='credentials_uri',
    # 憑證的 URI,格式為http://local_or_remote_uri/,可以通過環境變數ALIBABA_CLOUD_CREDENTIALS_URI設定credentials_uri
    credentials_uri='<credentials_uri>',
)
cred = Client(config)

credential = cred.get_credential()
access_key_id = credential.get_access_key_id()
access_key_secret = credential.get_access_key_secret()
security_token = credential.get_security_token()
cred_type = credential.get_type()

該地址必須滿足如下條件:

  • 支援GET請求。

  • 響應 200 狀態代碼。

  • 響應體為如下的結構:

    {
      "Code": "Success",
      "AccessKeySecret": "AccessKeySecret",
      "AccessKeyId": "AccessKeyId",
      "Expiration": "2021-09-26T03:46:38Z",
      "SecurityToken": "SecurityToken"
    }

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

from alibabacloud_credentials.client import Client as CredClient
from alibabacloud_credentials.models import Config as CredConfig
from alibabacloud_ecs20140526.client import Client as EcsClient
from alibabacloud_ecs20140526.models import DescribeRegionsRequest
from alibabacloud_tea_openapi.models import Config
from alibabacloud_tea_util.models import RuntimeOptions

# 使用URI憑據初始化Credentials Client。
credentialsConfig = CredConfig(
    # 憑證類型。
    type='credentials_uri',
    # 憑證的 URI,格式為http://local_or_remote_uri/,可以通過環境變數ALIBABA_CLOUD_CREDENTIALS_URI設定credentials_uri
    credentials_uri='<credentials_uri>',
)
credentialsClient = CredClient(credentialsConfig)
ecsConfig = Config(credential=credentialsClient)
# 配置雲產品服務接入地址(endpoint)。
ecsConfig.endpoint = 'ecs.aliyuncs.com'
# 使用Credentials Client初始化ECS Client。
ecsClient = EcsClient(ecsConfig)

# 初始化DescribeRegions請求。
request = DescribeRegionsRequest()
# 初始化運行時配置。
runtime_options = RuntimeOptions()
# 調用DescribeRegions介面並獲得響應。
response = ecsClient.describe_regions_with_options(request, runtime_options)
print(response.to_map())

方式八:使用Bearer Token

目前只有Cloud Call CenterCCC這款產品支援Bearer Token的憑據初始化方式。

from alibabacloud_credentials.client import Client
from alibabacloud_credentials.models import Config

config = Config(
	type='bearer',
	# 填入您的Bearer Token
	bearer_token='<BearerToken>',
)
cred = Client(config)

credential = cred.get_credential()
access_key_id = credential.get_access_key_id()
access_key_secret = credential.get_access_key_secret()
security_token = credential.get_security_token()
cred_type = credential.get_type()

介面調用方法

本樣本以調用話務中心CCC的GetInstance介面為例,因此需先安裝CCC SDK

from alibabacloud_credentials.client import Client as CredClient
from alibabacloud_credentials.models import Config as CredConfig
from alibabacloud_ccc20200701.client import Client as CCC20200701Client
from alibabacloud_ccc20200701 import models as ccc20200701_models
from alibabacloud_tea_openapi.models import Config
from alibabacloud_tea_util.models import RuntimeOptions

# 使用Bearer Token初始化Credentials Client。
credentialsConfig = CredConfig(
    type='bearer',  # 憑證類型。
    bearer_token='<bearer_token>',  # 伺服器端自動產生的Bearer Token,帶有效期間。
)
credentialsClient = CredClient(credentialsConfig)
config = Config(credential=credentialsClient)

# 配置雲產品服務接入地址(endpoint)。
config.endpoint = 'ccc.cn-shanghai.aliyuncs.com'
# 使用Credentials Client初始化CCC Client。
cccClient = CCC20200701Client(config)

request = ccc20200701_models.GetInstanceRequest(
    instance_id='ccc-test'
)
# 初始化運行時配置。
runtime_options = RuntimeOptions()
response = cccClient.get_instance_with_options(request, runtime_options)
print(response.to_map())

預設憑據鏈

當您的程式開發環境和生產環境採用不同的憑據類型,常見做法是在代碼中擷取當前環境資訊,編寫擷取不同憑據的分支代碼。藉助Credentials工具的預設憑據鏈,您可以用同一套代碼,通過程式之外的配置來控制不同環境下的憑據擷取方式。當您在不傳入參數的情況下,直接使用cred = CredClient()初始化憑據用戶端時,阿里雲SDK將會嘗試按照如下順序尋找相關憑據資訊。

1. 使用環境變數

如果未找到系統屬性中的憑據資訊,Credentials工具會繼續檢查環境變數。

  • 如果ALIBABA_CLOUD_ACCESS_KEY_ID ALIBABA_CLOUD_ACCESS_KEY_SECRET均存在且非空,則使用它們作為預設憑據。

  • 如果同時設定了ALIBABA_CLOUD_ACCESS_KEY_ID、ALIBABA_CLOUD_ACCESS_KEY_SECRETALIBABA_CLOUD_SECURITY_TOKEN,則使用STS Token作為預設憑據。

2. 使用OIDC RAM角色

如果未找到更高優先順序的憑據資訊,Credentials工具會檢查以下與OIDC RAM角色相關的環境變數:

  • ALIBABA_CLOUD_ROLE_ARN:RAM角色名稱ARN。

  • ALIBABA_CLOUD_OIDC_PROVIDER_ARN:OIDC供應商ARN。

  • ALIBABA_CLOUD_OIDC_TOKEN_FILE:OIDC Token檔案路徑。

如果以上三個變數均被設定且內容有效,Credentials將會使用變數內容調用STS服務的AssumeRoleWithOIDC介面換取STS Token作為預設憑據。

3. 使用設定檔

說明

該功能要求alibabacloud_credentials的版本不低於1.0rc3

如果未找到更高優先順序的憑據資訊,Credentials工具會嘗試載入config.json設定檔。該檔案的預設完整路徑如下:

  • Linux系統:~/.aliyun/config.json

  • Windows系統: C:\Users\USER_NAME\.aliyun\config.json

請注意,這些預設路徑不可更改為其他路徑。如果您需要通過此方式配置訪問憑據,您可以手動在相應路徑下建立config.json設定檔,內容格式樣本如下:

{
	"current": "default",
	"profiles": [
		{
			"name": "default",
			"mode": "AK",
			"access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
			"access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>"
		},
		{
			"name": "client",
			"mode": "StsToken",
			"access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
			"access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>",
			"sts_token": "<SECURITY_TOKEN>"
		},
		{
			"name":"client1",
			"mode":"RamRoleArn",
			"access_key_id":"<ALIBABA_CLOUD_ACCESS_KEY_ID>",
			"access_key_secret":"<ALIBABA_CLOUD_ACCESS_KEY_SECRET>",
			"ram_role_arn":"<ROLE_ARN>",
			"ram_session_name":"<ROLE_SESSION_NAME>",
			"expired_seconds":3600
		},
		{
			"name":"client2",
			"mode":"EcsRamRole",
			"ram_role_name":"<RAM_ROLE_ARN>"
		},
		{
			"name":"client3",
			"mode":"OIDC",
			"oidc_provider_arn":"<OIDC_PROVIDER_ARN>",
			"oidc_token_file":"<OIDC_TOKEN_FILE>",
			"ram_role_arn":"<ROLE_ARN>",
			"ram_session_name":"<ROLE_SESSION_NAME>",
			"expired_seconds":3600
		},
		{
			"name":"client4",
			"mode":"ChainableRamRoleArn",
			"source_profile":"<PROFILE_NAME>",
			"ram_role_arn":"<ROLE_ARN>",
			"ram_session_name":"<ROLE_SESSION_NAME>",
			"expired_seconds":3600
		}
	]
}

config.json設定檔中可以通過mode指定不同的憑據:

  • AK:使用使用者的Access Key作為憑據資訊;

  • StsToken:使用STS Token作為憑據資訊;

  • RamRoleArn:使用RAM角色的ARN來擷取憑據資訊;

  • EcsRamRole:利用ECS綁定的RAM角色來擷取憑據資訊;

  • OIDC:通過OIDC ARN和OIDC Token來擷取憑據資訊;

  • ChainableRamRoleArn:採用角色鏈的方式,通過指定JSON檔案中的其他憑據,以重新擷取新的憑據資訊。

說明

其中name為憑據名稱,其他參數請根據實際情況修改。

配置完成後,Credentials將根據設定檔中current所指定的憑據名稱,選擇對應的憑據初始化憑據用戶端。此外,還可以通過環境變數ALIBABA_CLOUD_PROFILE指定具體的憑據名稱,例如將ALIBABA_CLOUD_PROFILE的值設定為client1

4. 使用ECS執行個體RAM角色

若不存在優先順序更高的憑據資訊,Credentials工具將預設採用加固模式(IMDSv2)訪問ECS的中繼資料服務(Meta Data Server),以擷取ECS執行個體RAM角色的STS Token作為預設憑據資訊。程式會自動訪問ECS的中繼資料服務拿到RoleName資訊,再去擷取憑證,也就是兩次請求。若想減少一次請求,可以直接在環境變數中配置ALIBABA_CLOUD_ECS_METADATA來指定執行個體RAM角色名稱。在使用加固模式時若發生異常,將使用普通模式兜底來擷取訪問憑據。您也可以通過設定環境變數ALIBABA_CLOUD_IMDSV1_DISABLED,執行不同的異常處理邏輯:

  1. 當值為false時,會使用普通模式繼續擷取訪問憑據。

  2. 當值為true時,表示只能使用加固模式擷取訪問憑據,會拋出異常。

服務端是否支援IMDSv2,取決於您在伺服器的配置。

另外,您可以通過配置環境變數ALIBABA_CLOUD_ECS_METADATA_DISABLED=true來關閉ECS中繼資料的憑證訪問。

5. 使用Credentials工具URI

如果上述方式均未找到有效憑據資訊,Credentials工具會檢查環境變數ALIBABA_CLOUD_CREDENTIALS_URI,如果該變數存在且指向一個有效URI地址,Credentials會向該URI發起HTTP請求,擷取臨時安全憑證作為預設憑據。

Session類型憑據自動重新整理機制

Session類型憑據包含RamRoleArn、ECS執行個體RAM角色、OIDCRoleArn以及URI憑據。該類型憑據Credentials工具中內建了自動重新整理機制,在第一次調用服務擷取訪問憑據之後,Credentials工具會將擷取的訪問憑據儲存到緩衝中。當後續使用訪問憑據時,若當前系統時間仍在緩衝到期時間之前,將自動從緩衝中提取憑據;否則,將重新調用相應服務擷取訪問憑據,並更新緩衝中的值。

說明

針對ECS執行個體RAM角色憑據,Credentials工具會提前15分鐘重新整理緩衝中的值。

下面將採用單例模式建立憑據用戶端,並利用該憑據用戶端初始化雲產品用戶端。隨後,將通過多個時間段調用OpenAPI,以驗證是否使用了內部緩衝,並在緩衝到期後檢驗憑據是否會重新整理。

import os
import sys
import time
import threading
from functools import wraps
from threading import Lock

from alibabacloud_credentials.client import Client as CredentialClient
from alibabacloud_credentials.models import Config as CredentialConfig
from alibabacloud_ecs20140526.client import Client
from alibabacloud_ecs20140526.models import DescribeRegionsRequest
from alibabacloud_tea_openapi.models import Config as EcsConfig


#
# 單例裝飾器(安全執行緒)
#

def singleton(cls):
    """實現安全執行緒的單例模式"""
    instances = {}
    lock = Lock()

    @wraps(cls)
    def wrapper(*args, **kwargs):
        with lock:
            if cls not in instances:
                instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return wrapper


#
# 單例服務類
#

@singleton
class Credential:
    def __init__(self):
        self._client = self._init_client()

    @staticmethod
    def _init_client() -> CredentialClient:
        try:
            config = CredentialConfig(
                type="ram_role_arn",
                access_key_id=os.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                access_key_secret=os.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
                role_arn=os.getenv("ALIBABA_CLOUD_ROLE_ARN"),
                role_session_name="RamRoleArnTest",
                role_session_expiration=3600,
            )
            return CredentialClient(config)
        except Exception as e:
            raise RuntimeError(f"Credential initialization failed: {e}") from e

    @property
    def client(self) -> CredentialClient:
        return self._client


@singleton
class EcsClient:
    def __init__(self, credential: CredentialClient):
        self._client = self._init_client(credential)

    @staticmethod
    def _init_client(credential: CredentialClient) -> Client:
        try:
            ecs_config = EcsConfig(credential=credential)
            ecs_config.endpoint = 'ecs.cn-hangzhou.aliyuncs.com'
            return Client(ecs_config)
        except Exception as e:
            raise RuntimeError(f"ECS client initialization failed: {e}") from e

    @property
    def client(self) -> Client:
        return self._client


#
# 任務函數
#

def execute_task():
    try:
        # 擷取憑證和ECS用戶端
        credential = Credential().client.get_credential()
        ecs_client = EcsClient(Credential().client).client

        # 列印憑證資訊
        print("Time:", time.strftime("%Y-%m-%d %H:%M:%S"))
        print("AK ID:", credential.access_key_id)
        print("AK Secret:", credential.access_key_secret)
        print("STS Token:", credential.security_token)

        # 調用API查詢Region列表
        request = DescribeRegionsRequest()
        response = ecs_client.describe_regions(request)
        print("Invoke result:", response.to_map()["statusCode"])

    except Exception as e:
        print(f"ECS client execution failed: {e}")
        raise


def schedule_task():
    def run_execute_task():
        try:
            execute_task()
        except Exception as e:
            print(f"Task execution failed: {e}")
        finally:
            nonlocal task_count
            task_count += 1
            if task_count == len(DELAYS):
                print("All tasks completed. Exiting program.")
                sys.exit(0)

    def schedule_execution(delay):
        task_timer = threading.Timer(delay, run_execute_task)
        task_timer.start()
        return task_timer

    # 定時任務延遲定義
    DELAYS = [0, 600, 4200, 4300]
    task_count = 0

    timers = [schedule_execution(delay) for delay in DELAYS]

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("Program interrupted by user.")
        for timer in timers:
            timer.cancel()


if __name__ == "__main__":
    schedule_task()

image

根據日誌顯示結果進行分析:

  • 在第一次調用時,由於未緩衝憑據資訊,系統根據配置擷取憑據資訊。擷取到憑據後,憑據資訊被儲存在緩衝中。

  • 第二次調用所使用的憑據資訊與第一次相同,表明第二次調用是從緩衝中提取的憑據資訊。

  • 第三次調用時,由於憑據的到期時間(RoleSessionExpiration)被設定為3600秒,而第三次調用發生在第一次調用之後的4200秒,此時緩衝中的憑據已到期。因此,SDK依據自動重新整理機制重新擷取了新的憑據資訊,並將新擷取的憑據資訊再次儲存於緩衝中。

  • 第四次調用所使用的憑據資訊與第三次重新擷取的憑據資訊一致,這表明緩衝中的憑據在到期後已被更新為新的憑據。

相關文檔