全部產品
Search
文件中心

Alibaba Cloud SDK:管理訪問憑據

更新時間:Nov 23, 2024

在使用阿里雲SDK調用OpenAPI操作資源時,必須正確配置憑證資訊。Go V1.0 SDK支援多種憑據配置方式,本文詳細闡述了如何配置訪問憑據,以確保安全有效地使用SDK進行開發。

背景資訊

在使用阿里雲SDK進行開發時,需要根據具體的應用情境和授權需求選擇合適的訪問憑據類型,並正確配置和管理這些憑據。通過合理設定環境變數或設定檔,確保SDK能夠正確讀取和使用憑據,從而協助開發人員構建穩定、可靠的應用程式。

前提條件

  • Go 環境版本必須不低於 1.10.x。

  • 安裝 SDK 核心庫 Core

    go get -u github.com/aliyun/alibaba-cloud-sdk-go/sdk

初始化憑據用戶端

方式一:使用預設憑證鏈

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

package main

import (
    "github.com/aliyun/alibaba-cloud-sdk-go/sdk"
    "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider"
)

func main() {
    config := sdk.NewConfig()
    
    // 不傳參數
    credentialsProvider := credentials.NewDefaultCredentialsProvider()
    
    // <REGION_ID>:指定用戶端要訪問的阿里雲地區。樣本值:cn_hangzhou。
    sdk.NewClientWithOptions("<REGION_ID>", config, credentialsProvider)
    
    // 省略調用API步驟...
}

方式二:使用AK

阿里雲帳號和RAM使用者可以產生用於調用OpenAPI的AccessKey金鑰組,您可以使用該AccessKey初始化用戶端。

重要

由於主帳號AccessKey有資源完全的許可權,一旦泄露風險巨大。建議您使用RAM使用者的AccessKey,並設定定期輪換,建立RAM使用者AccessKey的方法請參見建立AccessKey

package main

import (
    "os"

    "github.com/aliyun/alibaba-cloud-sdk-go/sdk"
    "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
)

func main() {
    config := sdk.NewConfig()

    // 這裡通過環境變數擷取RAM使用者的AccessKey ID和AccessKey Secret,以避免寫入程式碼帶來的安全風險
    credentialsProvider := credentials.NewStaticAKCredentialsProvider(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
    
    // <REGION_ID>:指定用戶端要訪問的阿里雲地區。樣本值:cn_hangzhou
    sdk.NewClientWithOptions("<REGION_ID>", config, credentialsProvider)
    
    // 省略調用API步驟...
}

方式三:使用STS Token

通過Security Token Service(Security Token Service,簡稱 STS),申請臨時安全憑證(Temporary Security Credentials,簡稱 TSC),建立臨時安全用戶端。

package main

import (
    "os"

    "github.com/aliyun/alibaba-cloud-sdk-go/sdk"
    "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
)

func main() {
    config := sdk.NewConfig()

    // 這裡通過環境變數擷取RAM使用者的AccessKey ID、AccessKey Secret和STS Token,以避免寫入程式碼帶來的安全風險
    credentialsProvider := credentials.NewStaticSTSCredentialsProvider(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"), os.Getenv("ALIBABA_CLOUD_SECURITY_TOKEN"))
    
    // <REGION_ID>:指定用戶端要訪問的阿里雲地區。樣本值:cn_hangzhou。
    client, err := sdk.NewClientWithOptions("<REGION_ID>", config, credentialsProvider)
    
    // 省略調用API步驟...
}

方式四:使用AK及RamRoleArn

通過指定RAM角色的ARN(Alibabacloud Resource Name)來初始化用戶端。用戶端在發起請求前,需先通過調用STS服務擷取STS Token。若需限制STS Token的許可權,可使用自訂權限原則.

package main

import (
    "os"

    "github.com/aliyun/alibaba-cloud-sdk-go/sdk"
    "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
)

func main() {
    config := sdk.NewConfig()
    
    credentialsProvider := credentials.NewRamRoleArnWithPolicyAndExternalIdCredential(
        // os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"):從環境變數中擷取RAM使用者AccessKey ID
        os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
        // os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"):從環境變數中擷取RAM使用者AccessKey Secret
        os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
        // "<ROLE_ARN>":指定要扮演的RAM角色的ARN。樣本值:acs:ram::123456789012****:role/adminrole。
        "<ROLE_ARN>",
        // "<ROLE_SESSION_NAME>":指定角色會話的名稱,用於標識和區分不同的會話。樣本值:alice。
        "<ROLE_SESSION_NAME>",
        // "<POLICY>":指定一個自訂的授權策略用於限制角色會話的許可權。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}。
        "<POLICY>",
        // "<EXTERNAL_ID>":指定一個角色外部ID,防止混淆代理人問題。樣本值:abcd1234。
        "<EXTERNAL_ID>",
        // <ROLE_SESSION_EXPIRATION>:Token 有效期間。樣本值:3600。
        "<ROLE_SESSION_EXPIRATION>"
    )
    
    // <REGION_ID>:指定用戶端要訪問的阿里雲地區。樣本值:cn_hangzhou
    client, err := sdk.NewClientWithOptions("<REGION_ID>", config, credentialsProvider)
    
    // 省略調用API步驟...
}

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

ECS和ECI執行個體均支援綁定執行個體RAM角色,當在執行個體中使用Credentials工具時,將自動擷取執行個體綁定的RAM角色,並通過訪問中繼資料服務擷取RAM角色的STS Token,以完成憑據用戶端的初始化。

執行個體中繼資料服務器支援加固模式和普通模式兩種訪問方式,Credentials工具預設使用加固模式(IMDSv2)擷取訪問憑據。若使用加固模式時發生異常,您可以通過環境變數ALIBABA_CLOUD_IMDSV1_DISABLED,執行不同的異常處理邏輯:

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

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

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

說明
package main

import (
    "os"

    "github.com/aliyun/alibaba-cloud-sdk-go/sdk"
    "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
)

func main() {
    
    // 通過ECS執行個體的RAM角色來擷取訪問憑證,從而建立一個阿里雲用戶端
    // 它適用於那些需要在ECS執行個體上運行,並且需要訪問其他阿里雲資源的程式
    // "<ROLE_NAME>":指定要使用的RAM角色名稱,您可以在環境變數ALIBABA_CLOUD_ECS_METADATA中設定 roleName 預設值。樣本值:alice。
   credentialsProvider := credentials.NewECSRAMRoleCredentialsProvider("<ROLE_NAME>")
   
   // <REGION_ID>:指定用戶端要訪問的阿里雲地區。樣本值:cn_hangzhou。
   client, err := sdk.NewClientWithOptions("<REGION_ID>", config, credentialsProvider)

   // 省略調用API步驟...
}

方式六:使用OIDCRoleArn

Container Service Kubernetes 版中,設定 Worker 節點 RAM 角色後,節點內的 Pod 可以通過中繼資料服務擷取關聯角色的 STS Token。然而,對於不可信的應用(如客戶提交的未公開代碼的應用),直接通過中繼資料服務擷取 STS Token 可能會帶來安全風險。為瞭解決這一問題並實現應用層級的許可權最小化,可以使用 RRSA(RAM Roles for Service Account)功能。這有助於確保雲上資源的安全性,同時允許不可信應用安全地擷取所需的 STS Token。阿里雲容器叢集會為不同的應用Pod建立和掛載相應的服務賬戶OIDC Token檔案,並將相關配置資訊注入到環境變數中,Credentials工具通過擷取環境變數的配置資訊,調用STS服務的AssumeRoleWithOIDC - OIDC角色SSO時擷取扮演角色的臨時身份憑證介面換取綁定角色的STS Token。詳情請參見通過RRSA配置ServiceAccount的RAM許可權實現Pod許可權隔離。注入的環境變數如下:

ALIBABA_CLOUD_ROLE_ARN:RAM角色名稱ARN;

ALIBABA_CLOUD_OIDC_PROVIDER_ARN:OIDC供應商ARN;

ALIBABA_CLOUD_OIDC_TOKEN_FILE:OIDC Token檔案路徑;

package main

import (
	"os"

	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
)

func main() {
    config := sdk.NewConfig()

    // 使用OIDCRoleArn初始化SDK用戶端
    oidcProvider, _ := credentials.NewOIDCCredentialsProviderBuilder().
	// OIDC供應商ARN,可以通過環境變數ALIBABA_CLOUD_OIDC_PROVIDER_ARN設定OIDCProviderARN
	WithOIDCProviderARN(os.Getenv("ALIBABA_CLOUD_OIDC_PROVIDER_ARN")).
	// OIDC Token檔案路徑,可以通過環境變數ALIBABA_CLOUD_OIDC_TOKEN_FILE設定OIDCTokenFilePath
	WithOIDCTokenFilePath(os.Getenv("ALIBABA_CLOUD_OIDC_TOKEN_FILE")).
	// RAM角色名稱ARN,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定RoleArn
	WithRoleArn(os.Getenv("ALIBABA_CLOUD_ROLE_ARN")).
	// "<ROLE_SESSION_NAME>":自訂角色會話名稱。樣本值:alice。
	WithRoleSessionName("<ROLE_SESSION_NAME>").
	// "<POLICY>":設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}。
	WithPolicy("<POLICY>").
	// <ROLE_SESSION_EXPIRATION>:設定session到期時間。樣本值:3600。
	WithDurationSeconds( "<ROLE_SESSION_EXPIRATION>").
	Build()
        
        // <REGION_ID>:指定用戶端要訪問的阿里雲地區。樣本值:cn_hangzhou。
	client, err := sdk.NewClientWithOptions("<REGION_ID>", config, oidcProvider)

        // 省略調用API步驟...
}

方式七:使用Bearer Token

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

package main

import (
    "github.com/aliyun/alibaba-cloud-sdk-go/sdk"
    "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
)

func main() {
    config := sdk.NewConfig()

    // <BEARER_TOKEN>是一種認證方式,用於授權訪問API
    credentialsProvider := credentials.NewBearerTokenCredentialsProvider("BEARER_TOKEN")
    
    // <REGION_ID>:指定用戶端要訪問的阿里雲地區。樣本值:cn_hangzhou。
    client, err := sdk.NewClientWithOptions("<REGION_ID>", config, credentialsProvider)

    // 省略調用API步驟...
}

預設憑據鏈

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

1. 使用環境變數

若不存在優先順序更高的憑據資訊,Credentials工具會優先在環境變數中擷取憑據資訊。

  • 如果系統內容變數ALIBABA_CLOUD_ACCESS_KEY_ID(密鑰Key) ALIBABA_CLOUD_ACCESS_KEY_SECRET(密鑰Value) 不為空白,Credentials工具會優先使用它們作為預設憑據。

  • 如果系統內容變數ALIBABA_CLOUD_ACCESS_KEY_ID(密鑰Key)、ALIBABA_CLOUD_ACCESS_KEY_SECRET(密鑰Value)、ALIBABA_CLOUD_SECURITY_TOKEN(Token)均不為空白,Credentials工具會優先使用STS Token作為預設憑據。

2. 使用OIDC RAM角色

若不存在優先順序更高的憑據資訊,Credentials工具會在環境變數中擷取如下內容:

ALIBABA_CLOUD_ROLE_ARN:RAM角色名稱ARN;

ALIBABA_CLOUD_OIDC_PROVIDER_ARN:OIDC供應商ARN;

ALIBABA_CLOUD_OIDC_TOKEN_FILE:OIDC Token檔案路徑;

若以上三個環境變數都已設定內容,Credentials將會使用變數內容調用STS服務的AssumeRoleWithOIDC - OIDC角色SSO時擷取扮演角色的臨時身份憑證介面換取STS Token作為預設憑據。

3. 使用config.json設定檔

若不存在優先順序更高的憑據資訊,Credentials工具會優先在如下位置尋找config.json檔案是否存在:

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

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

如果檔案存在,程式將會使用設定檔中current 指定的憑據資訊初始化憑據用戶端。當然,您也可以通過環境變數 ALIBABA_CLOUD_PROFILE 來指定憑據資訊,例如設定 ALIBABA_CLOUD_PROFILE 的值為client1

config.json設定檔中每個mode的值代表了不同的憑據資訊擷取方式:

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

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

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

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

  • ChainableRamRoleArn:採用角色鏈的方式,通過指定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":"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
		}
	]
}

4. ECS執行個體RAM角色

若不存在優先順序更高的憑據資訊,Credentials工具將通過環境變數擷取ALIBABA_CLOUD_ECS_METADATA(ECS執行個體RAM角色名稱)的值。若該變數的值存在,程式將採用加固模式(IMDSv2)訪問ECS的中繼資料服務(Meta Data Server),以擷取ECS執行個體RAM角色的STS Token作為預設憑據資訊。在使用加固模式時若發生異常,將使用普通模式兜底來擷取訪問憑據。您也可以通過設定環境變數ALIBABA_CLOUD_IMDSV1_DISABLED,執行不同的異常處理邏輯:

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

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

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

5. 使用Credentials工具URI

若不存在優先順序更高的憑據資訊,Credentials工具會在環境變數中擷取ALIBABA_CLOUD_CREDENTIALS_URI,若存在,程式將請求該URI地址,擷取臨時安全憑證作為預設憑據資訊。

相關文檔