在使用阿里雲SDK時,憑據資訊(例如AccessKey、STS Token等)由Credentials工具統一管理。本文將為您介紹Credentials工具支援的憑據類型及其配置方法,協助您快速掌握Credentials工具的使用。
背景資訊
憑據是指使用者證明其身份的一組資訊。使用者在系統中進行登入時,需要提供正確的憑據才能驗證身份。常見的憑據類型有:
阿里雲主帳號和RAM使用者的永久憑據 AccessKey(簡稱AK)是由AccessKey ID和AccessKey Secret組成的金鑰組。
阿里雲RAM角色的STS臨時訪問Token,簡稱STS Token。它是可以自訂時效和存取權限的臨時身份憑據,詳情請參見什麼是STS。
Bearer Token。它是一種身分識別驗證和授權的令牌類型。
前提條件
使用Credentials工具要求Go版本 >= 1.10.x。
使用V2.0代系的阿里雲SDK,詳情請參見通過IDE使用阿里雲Go SDK。
安裝Credentials工具
如果已安裝Credentials工具,可跳過本步驟。建議使用最新版本的Credentials依賴包,以確保全面支援所有憑據類型。您可以在Credentials中查看所有發行版本的資訊。
Credentials 工具可通過以下任意方式安裝:
方式一:使用
go get下載安裝:$ go get -u github.com/aliyun/credentials-go方式二:如果您使用
dep來管理依賴包,您可以使用以下命令:dep ensure -add github.com/aliyun/credentials-go
Credentials工具配置參數介紹
Credentials工具的配置參數定義在github.com/aliyun/credentials-go/credentials包的Config結構體中,憑據類型由必填參數type指定。確定憑據類型後,需根據該憑據類型選擇相應的參數。下表將詳細介紹type的取值範圍及各類憑據類型所支援的參數。其中,√表示必填參數,-表示選擇性參數,×表示不支援參數。
未在下表中列出的憑據類型及參數表示不建議繼續使用。
Type | access_key | sts | ram_role_arn | ecs_ram_role | oidc_role_arn | credentials_uri | bearer |
AccessKeyId:訪問憑據ID。 | √ | √ | √ | × | × | × | × |
AccessKeySecret:訪問憑據密鑰。 | √ | √ | √ | × | × | × | × |
SecurityToken:STS Token。 | × | √ | - | × | × | × | × |
RoleArn:RAM角色的ARN。 | × | × | √ | × | √ | × | × |
RoleSessionName:自訂會話名稱,預設格式為 | × | × | - | × | - | × | × |
RoleName:RAM角色名稱。 | × | × | × | - | × | × | × |
DisableIMDSv1:是否強制使用加固模式,預設值為 | × | × | × | - | × | × | × |
BearerToken:bearer token。 | × | × | × | × | × | × | √ |
Policy:自訂權限原則。 | × | × | - | × | - | × | × |
RoleSessionExpiration:會話到期時間,預設3600秒。 | × | × | - | × | - | × | × |
OIDCProviderArn:OIDC供應商ARN。 | × | × | × | × | √ | × | × |
OIDCTokenFilePath:OIDC Token檔案路徑。 | × | × | × | × | √ | × | × |
ExternalId:角色外部 ID,主要功能是防止混淆代理人問題。更多資訊,請參見使用ExternalId防止混淆代理人問題。 | × | × | - | × | × | × | × |
Url:憑證的URI,該參數需通過SetURLCredential(v string)賦值。 | × | × | × | × | × | √ | × |
STSEndpoint:STS的服務存取點,支援VPC服務存取點和公網服務存取點,可選的值請參見服務存取點,預設值為 | × | × | - | × | - | × | × |
Timeout:HTTP請求的讀逾時時間,預設值為5000毫秒。 | × | × | - | - | - | - | × |
ConnectTimeout:HTTP請求的連線逾時時間,預設值為10000毫秒。 | × | × | - | - | - | - | × |
初始化憑據用戶端
前文已介紹Credentials工具所支援的憑據類型及其配置參數,接下來將通過詳細的程式碼範例進一步說明,您可以根據具體情況選擇適合的使用方式。
在專案中使用明文AccessKey,容易因代碼倉庫許可權管理不當造成AccessKey泄露,會威脅該帳號下所有資源的安全。建議通過環境變數、設定檔等方式儲存AccessKey。
在使用Credentials工具時,建議採用單例模式。這一做法能夠啟用Credentials工具內建的憑據緩衝功能,有效防止因多次調用介面而導致的限流問題,以及因建立多個執行個體而引起的資源浪費問題。詳細資料請參見Session類型憑據自動重新整理機制。
方式一:使用預設憑據鏈
當您在初始化憑據用戶端不傳入任何參數時,Credentials會使用預設憑據鏈方式初始化用戶端。預設憑據的讀取邏輯請參見預設憑據鏈。
package main
import (
"fmt"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials"
)
func main() {
// 不指定參數或者傳入nil
credential, err := credentials.NewCredential(nil)
config := &openapi.Config{}
config.Credential = credential
// 省略使用config初始化雲產品client部分內容,具體請參見介面調用樣本
}介面調用樣本
方式二:使用AK
Credentials工具將使用您提供的AccessKey作為訪問憑據。
阿里雲帳號(主帳號)擁有資源的全部許可權,AK一旦泄露,會給系統帶來巨大風險,不建議使用。
推薦使用最小化授權的RAM使用者的AK。
import (
"fmt"
"os"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials"
)
func main() {
config := new(credentials.Config).
SetType("access_key").
SetAccessKeyId(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")).
SetAccessKeySecret(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
akCredential, err := credentials.NewCredential(config)
if err != nil {
return
}
config := &openapi.Config{}
config.Credential = akCredential
// 省略使用config初始化雲產品client部分內容,具體請參見介面調用樣本
}介面調用樣本
方式三:使用STS Token
Credentials工具將使用您提供的靜態STS Token作為訪問憑據。
package main
import (
"fmt"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials"
"os"
)
func main() {
config := new(credentials.Config).
SetType("sts").
// 從環境變數中擷取AccessKey Id。
SetAccessKeyId(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")).
// 從環境變數中擷取AccessKey Secret
SetAccessKeySecret(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")).
// 從環境變數中擷取STS臨時憑證。
SetSecurityToken(os.Getenv("ALIBABA_CLOUD_SECURITY_TOKEN"))
stsCredential, err := credentials.NewCredential(config)
if err != nil {
return
}
config := &openapi.Config{}
config.Credential = stsCredential
// 省略使用config初始化雲產品client部分內容,具體請參見介面調用樣本
}
介面調用樣本
方式四:使用AK及RamRoleArn
該方式底層實現是STS Token。通過指定RAM角色的ARN(Alibabacloud Resource Name),Credentials工具可以協助開發人員前往STS換取STS Token。您也可以通過為SetPolicy賦值來限制RAM角色到一個更小的許可權集合。
package main
import (
"fmt"
"os"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials"
)
func main() {
config := new(credentials.Config).
SetType("ram_role_arn").
SetAccessKeyId(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")).
SetAccessKeySecret(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")).
// 要扮演的RAM角色ARN,樣本值:acs:ram::123456789012****:role/adminrole,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定RoleArn
SetRoleArn("<RoleArn>").
// 角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定RoleSessionName
SetRoleSessionName("<RoleSessionName>").
// 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
SetPolicy("<Policy>").
// 非必填,設定session到期時間。
SetRoleSessionExpiration(3600).
// 非必填,角色外部 ID,該參數為外部提供的用於表示角色的參數資訊,主要功能是防止混淆代理人問題。
SetExternalId("ExternalId").
// 非必填,預設為sts.aliyuncs.com,建議使用Region化的STS網域名稱,選擇地理位置更接近的Region可以保證網路連通性.
SetSTSEndpoint("sts.cn-hangzhou.aliyuncs.com")
arnCredential, err := credentials.NewCredential(config)
if err != nil {
return
}
config := &openapi.Config{}
config.Credential = arnCredential
// 省略使用config初始化雲產品client部分內容,具體請參見介面調用樣本
}
ExternalId的更多介紹,請參見使用ExternalId防止混淆代理人問題。
介面調用樣本
方式五:使用ECS執行個體RAM角色
ECS和ECI執行個體均支援綁定執行個體RAM角色,運行於執行個體中的程式可通過Credentials工具自動擷取該角色的STS Token,從而完成憑據用戶端的初始化。
Credentials工具將預設採用加固模式(IMDSv2)訪問ECS的中繼資料服務(Meta Data Server),在使用加固模式時若發生異常,將使用普通模式兜底來擷取訪問憑據。您也可以通過設定參數disableIMDSv1或環境變數ALIBABA_CLOUD_IMDSV1_DISABLE,執行不同的異常處理邏輯:
當值為false(預設)時,會使用普通模式繼續擷取訪問憑據。
當值為true時,表示只能使用加固模式擷取訪問憑據,會拋出異常。
服務端是否支援IMDSv2,取決於您在伺服器的配置。
另外,您可以通過配置環境變數ALIBABA_CLOUD_ECS_METADATA_DISABLED=true來關閉ECS中繼資料的憑證訪問。
使用加固模式擷取臨時身份憑證時,credentials-go的版本不低於1.3.10。
關於ECS執行個體中繼資料的介紹,請參見執行個體中繼資料。
如何為ECS和ECI執行個體授予RAM角色,具體操作請參見建立RAM角色並授予ECS執行個體和為ECI執行個體授予執行個體RAM角色。
package main
import (
"fmt"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials"
)
func _main(args []*string) {
// 使用EcsRamRole初始化Credentials Client。
credentialsConfig := new(credentials.Config).
// 憑證類型。
SetType("ecs_ram_role").
// 選填,該ECS角色的角色名稱,不填會自動擷取,但是建議加上以減少請求次數,可以通過環境變數ALIBABA_CLOUD_ECS_METADATA設定RoleName
SetRoleName("<RoleName>")
// 選填,預設值:false。true:表示強制使用加固模式。false:系統將首先嘗試在加固模式下擷取憑據。如果失敗,則會切換到普通模式(IMDSv1)進行嘗試
// credentialsConfig.SetDisableIMDSv1(true)
credentialClient, err := credentials.NewCredential(credentialsConfig)
if err != nil {
return
}
config := &openapi.Config{}
config.Credential = credentialClient
// 省略使用config初始化雲產品client部分內容,具體請參見介面調用樣本。
}
介面調用樣本
方式六:使用OIDCRoleArn
若您使用OIDC認證協議,並已建立OIDC身份供應商的RAM角色,您可以通過Credentials工具傳入OIDC身份供應商ARN、OIDC Token及RAM角色ARN,系統將自動調用AssumeRoleWithOIDC介面擷取RAM角色的STS Token,並將該STS Token作為訪問憑據。通過此方式擷取的憑據支援自動重新整理,詳情請參見Session類型憑據自動重新整理機制。例如當您的應用程式運行於已啟用RRSA功能的ACK叢集中時,Credentials工具支援通過讀取Pod環境變數中的OIDC配置資訊,調用AssumeRoleWithOIDC介面擷取服務角色的STS Token,從而利用該STS Token訪問阿里雲相關服務。
package main
import (
"fmt"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials"
"os"
)
func main() {
config := new(credentials.Config).
SetType("oidc_role_arn").
// OIDC供應商ARN,可以通過環境變數ALIBABA_CLOUD_OIDC_PROVIDER_ARN設定OidcProviderArn
SetOIDCProviderArn(os.Getenv("ALIBABA_CLOUD_OIDC_PROVIDER_ARN")).
// OIDC Token檔案路徑,可以通過環境變數ALIBABA_CLOUD_OIDC_TOKEN_FILE設定OidcTokenFilePath
SetOIDCTokenFilePath(os.Getenv("ALIBABA_CLOUD_OIDC_TOKEN_FILE")).
// RAM角色名稱ARN,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定RoleArn
SetRoleArn(os.Getenv("ALIBABA_CLOUD_ROLE_ARN")).
// 角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定RoleSessionName
SetRoleSessionName(os.Getenv("ALIBABA_CLOUD_ROLE_SESSION_NAME")).
// 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
SetPolicy("<Policy>").
// 非必填,設定session到期時間
SetRoleSessionExpiration(3600).
// 非必填,預設為sts.aliyuncs.com,建議使用Region化的STS網域名稱,選擇地理位置更接近的Region可以保證網路連通性
SetSTSEndpoint("sts.cn-hangzhou.aliyuncs.com")
oidcCredential, err := credentials.NewCredential(config)
if err != nil {
return
}
config := &openapi.Config{}
config.Credential = oidcCredential
// 省略使用config初始化雲產品client部分內容,具體請參見介面調用樣本。
}
介面調用樣本
方式七:使用URI憑據
通過封裝STS服務並對外暴露服務的URI,外部服務能夠通過該URI擷取STS Token,從而有效降低AK等敏感資訊的暴露風險。Credentials工具支援通過訪問您所提供的URI來擷取STS Token,並將該STS Token作為訪問憑據。通過此方式擷取的憑據支援自動重新整理,詳情請參見Session類型憑據自動重新整理機制。
package main
import (
"github.com/aliyun/credentials-go/credentials"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
)
func main() {
config := new(credentials.Config).
SetType("credentials_uri").
// 憑證的 URI,格式為http://local_or_remote_uri/,可以通過環境變數ALIBABA_CLOUD_CREDENTIALS_URI設定CredentialsUri
SetURLCredential("<CredentialsUri>")
uriCredential, err := credentials.NewCredential(config)
config := &openapi.Config{}
config.Credential = uriCredential
// 省略使用config初始化雲產品client部分內容,具體請參見介面調用樣本。
}
該地址必須滿足如下條件:
支援GET請求。
響應體為如下的結構:
{ "AccessKeySecret": "AccessKeySecret", "AccessKeyId": "AccessKeyId", "Expiration": "2021-09-26T03:46:38Z", "SecurityToken": "SecurityToken" }
介面調用樣本
方式八:使用Bearer Token
目前只有Cloud Call CenterCCC這款產品支援Bearer Token的憑據初始化方式。
package main
import (
"fmt"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials"
)
func main() {
config := new(credentials.Config).
SetType("bearer").
// 填入您的Bearer Token
SetBearerToken("<BearerToken>")
bearerCredential, err := credentials.NewCredential(config)
if err != nil {
return
}
config := &openapi.Config{}
config.Credential = bearerCredential
// 省略使用config初始化雲產品client部分內容,具體請參見介面調用樣本。
}介面調用樣本
方式九:使用CLIProfileCredentialsProvider
從阿里雲CLI憑據配置隱藏檔(config.json)中擷取訪問憑據。
package main
import (
"github.com/aliyun/credentials-go/credentials"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials/providers"
)
func main() {
// CLIProfileCredentialsProvider
provider, err := providers.NewCLIProfileCredentialsProviderBuilder().
// 憑據名稱,非必填。支援多種方式配置,優先順序從高到低:顯示指定的profileName -> 使用環境變數ALIBABA_CLOUD_CONFIG_FILE指定的profileName -> 預設讀取config.json中的current.
WithProfileName("<PROFILE_NAME>").
// 設定檔路徑,必須是一個.json檔案,非必填。支援多種方式配置,優先順序從高到低:顯示指定的profileFile -> 使用環境變數ALIBABA_CLOUD_CONFIG_FILE指定的profileFile -> 預設讀取 ~/.aliyun/config.json.
WithProfileFile("<PROFILE_FILE_PATH>").
Build()
if err != nil {
return
}
credential := credentials.FromCredentialsProvider("cli_profile", provider)
config := &openapi.Config{}
config.Credential = credential
// 省略使用config初始化雲產品client部分內容,具體請參見介面調用樣本。
}您可以通過阿里雲CLI配置憑證,或者手動在以下路徑建立config.json設定檔:
Linux系統:
~/.aliyun/config.jsonWindows系統:
C:\Users\USER_NAME\.aliyun\config.json
內容格式如下:
{
"current": "<PROFILE_NAME>",
"profiles": [
{
"name": "<PROFILE_NAME>",
"mode": "AK",
"access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
"access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>"
},
{
"name": "<PROFILE_NAME1>",
"mode": "StsToken",
"access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
"access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>",
"sts_token": "<SECURITY_TOKEN>"
},
{
"name":"<PROFILE_NAME2>",
"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":"<PROFILE_NAME3>",
"mode":"EcsRamRole",
"ram_role_name":"<RAM_ROLE_ARN>"
},
{
"name":"<PROFILE_NAME4>",
"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":"<PROFILE_NAME5>",
"mode":"ChainableRamRoleArn",
"source_profile":"<PROFILE_NAME>",
"ram_role_arn":"<ROLE_ARN>",
"ram_session_name":"<ROLE_SESSION_NAME>",
"expired_seconds":3600
},
{
"name": "<PROFILE_NAME6>",
"mode": "CloudSSO",
"cloud_sso_sign_in_url": "https://******/login",
"access_token": "eyJraWQiOiJiYzViMzUwYy******",
"cloud_sso_access_token_expire": 1754316142,
"cloud_sso_access_config": "ac-00s1******",
"cloud_sso_account_id": "151266******"
}
]
}
在config.json設定檔中可以通過mode指定不同的憑據:
AK:使用使用者的Access Key作為憑據資訊;
StsToken:使用STS Token作為憑據資訊;
RamRoleArn:使用RAM角色的ARN來擷取憑據資訊;
EcsRamRole:利用ECS綁定的RAM角色來擷取憑據資訊;
OIDC:通過OIDC ARN和OIDC Token來擷取憑據資訊;
ChainableRamRoleArn:採用角色鏈的方式,通過
source_profile指定config.json設定檔中其他憑據的名稱,以重新擷取新的憑據資訊。CloudSSO:雲SSO使用者使用阿里雲CLI擷取的憑據資訊。
說明CloudSSO憑據要求
github.com/aliyun/credentials-go的版本不低於1.4.7,且配置內容僅支援通過阿里雲CLI擷取,具體資訊請參見使用CLI登入雲SSO並訪問阿里雲資源。
配置完成後,Credentials將根據指定的憑據名稱,選擇對應的憑據初始化憑據用戶端。
介面調用樣本
預設憑據鏈
當開發環境與生產環境使用的憑據類型不一致時,常見做法是在代碼中擷取當前環境資訊,編寫擷取不同憑據的分支代碼。藉助Credentials工具的預設憑據鏈,您可以用同一套代碼,通過程式之外的配置來控制不同環境下的憑據擷取方式。當您使用NewCredential()初始化憑據用戶端,且不傳入任何參數時,阿里雲SDK將會嘗試按照如下順序尋找相關憑據資訊。
1. 使用環境變數
如果未找到系統屬性中的憑據資訊,Credentials工具會繼續檢查環境變數。
如果 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET 均存在且非空,則使用它們作為預設憑據。
如果同時設定了 ALIBABA_CLOUD_ACCESS_KEY_ID、ALIBABA_CLOUD_ACCESS_KEY_SECRET 和 ALIBABA_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. 使用config.json設定檔
如果未找到更高優先順序的憑據資訊,Credentials工具會嘗試載入config.json設定檔。該設定檔的預設完整路徑如下:
Linux/Mac系統:
~/.aliyun/config.jsonWindows系統:
C:\Users\USER_NAME\.aliyun\config.json
自github.com/aliyun/credentials-go@1.4.4版本起,支援通過環境變數 ALIBABA_CLOUD_CONFIG_FILE 自訂config.json設定檔的路徑,該環境變數的優先順序高於預設路徑。
如果您需要通過此方式配置訪問憑據,可以使用阿里雲CLI配置憑證,或者手動在相應路徑下建立config.json設定檔,內容格式樣本如下:
{
"current": "<PROFILE_NAME>",
"profiles": [
{
"name": "<PROFILE_NAME>",
"mode": "AK",
"access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
"access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>"
},
{
"name": "<PROFILE_NAME1>",
"mode": "StsToken",
"access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
"access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>",
"sts_token": "<SECURITY_TOKEN>"
},
{
"name": "<PROFILE_NAME2>",
"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": "<PROFILE_NAME3>",
"mode": "EcsRamRole",
"ram_role_name": "<RAM_ROLE_ARN>"
},
{
"name": "<PROFILE_NAME4>",
"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": "<PROFILE_NAME5>",
"mode": "ChainableRamRoleArn",
"source_profile": "<PROFILE_NAME>",
"ram_role_arn": "<ROLE_ARN>",
"ram_session_name": "<ROLE_SESSION_NAME>",
"expired_seconds": 3600
},
{
"name": "<PROFILE_NAME6>",
"mode": "CloudSSO",
"cloud_sso_sign_in_url": "https://******/login",
"access_token": "eyJraWQiOiJiYzViMzUwYy******",
"cloud_sso_access_token_expire": 1754316142,
"cloud_sso_access_config": "ac-00s1******",
"cloud_sso_account_id": "151266******"
},
{
"name": "<PROFILE_NAME7>",
"mode": "OAuth",
"access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
"access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>",
"sts_token": "<SECURITY_TOKEN>",
"region_id": "<REGION_ID>",
"output_format": "json",
"language": "<zh|en>",
"sts_expiration": "<STS_EXPIRATION>",
"oauth_access_token": "<OAUTH_ACCESS_TOKEN>",
"oauth_refresh_token": "<OAUTH_REFRESH_TOKEN>",
"oauth_access_token_expire": 1754316142,
"oauth_site_type": "<CN|EN>"
}
]
}在config.json設定檔中可以通過mode指定不同的憑據:
AK:使用使用者的Access Key作為憑據資訊;
StsToken:使用STS Token作為憑據資訊;
RamRoleArn:使用RAM角色的ARN來擷取憑據資訊;
EcsRamRole:利用ECS綁定的RAM角色來擷取憑據資訊;
OIDC:通過OIDC ARN和OIDC Token來擷取憑據資訊;
ChainableRamRoleArn:採用角色鏈的方式,通過
source_profile指定config.json設定檔中其他憑據的名稱,以重新擷取新的憑據資訊。OAuth: 使用CLI通過OAuth登入方式來擷取的憑據資訊。
CloudSSO:雲SSO使用者使用阿里雲CLI擷取的憑據資訊。
OAuth憑據要求
github.com/aliyun/credentials-go的版本不低於1.4.8,且配置內容僅支援通過阿里雲CLI擷取,具體資訊請參見使用CLI擷取OAuth憑證。CloudSSO憑據要求
github.com/aliyun/credentials-go的版本不低於1.4.7,且配置內容僅支援通過阿里雲CLI擷取,具體資訊請參見使用CLI登入雲SSO並訪問阿里雲資源。
配置完成後,Credentials將根據設定檔中current所指定的憑據名稱,選擇對應的憑據初始化憑據用戶端。此外,還可以通過環境變數 ALIBABA_CLOUD_PROFILE 指定具體的憑據名稱,例如將 ALIBABA_CLOUD_PROFILE 的值設定為client1。
4. 使用ECS執行個體RAM角色
如果未找到更高優先順序的憑據資訊,Credentials會嘗試通過ECS執行個體綁定的RAM角色擷取憑據。預設情況下,Credentials會使用加固模式(IMDSv2)訪問ECS的中繼資料服務(Meta Data Server),以擷取ECS執行個體RAM角色的STS Token作為預設憑據資訊。程式會自動訪問ECS的中繼資料服務拿到RoleName資訊,再去擷取憑證,也就是兩次請求。若想減少一次請求,可以直接在環境變數中配置 ALIBABA_CLOUD_ECS_METADATA 來指定執行個體RAM角色名稱。在使用加固模式時若發生異常,將使用普通模式兜底來擷取訪問憑據。您也可以通過設定環境變數 ALIBABA_CLOUD_IMDSV1_DISABLE,執行不同的異常處理邏輯:
當值為false時,會使用普通模式繼續擷取訪問憑據。
當值為true時,表示只能使用加固模式擷取訪問憑據,會拋出異常。
服務端是否支援IMDSv2,取決於您在伺服器的配置。
另外,您可以通過配置環境變數ALIBABA_CLOUD_ECS_METADATA_DISABLED=true來關閉ECS中繼資料的憑證訪問。
關於ECS執行個體中繼資料的介紹,請參見執行個體中繼資料。
如何為ECS和ECI執行個體授予RAM角色,具體操作請參見建立RAM角色並授予ECS執行個體和為ECI執行個體授予執行個體RAM角色。
5. 使用Credentials工具URI
如果仍未擷取到憑據資訊,Credentials工具會檢查環境變數 ALIBABA_CLOUD_CREDENTIALS_URI,如果該變數存在且指向一個有效URI地址,Credentials通過訪問該URI來擷取STS Token作為預設憑據。
Session類型憑據自動重新整理機制
Session類型憑據包含ram_role_arn、ecs_ram_role、oidc_role_arn以及credentials_uri,該類型憑據在Credentials工具中內建了憑據自動重新整理機制。當憑據用戶端首次擷取憑據後,Credentials工具會將擷取的憑據資訊儲存至緩衝中。在後續使用過程中,同一憑據用戶端執行個體將自動從緩衝中提取憑據;若緩衝中的憑據資訊已到期,則憑據用戶端執行個體將重新擷取憑據,並更新緩衝中的值。
對於ecs_ram_role類型憑據,Credentials工具將會在緩衝中的值到期前15分鐘進行提前重新整理。
下面將採用單例模式建立憑據用戶端,通過多個時間段擷取憑據來驗證憑據重新整理機制,並通過調用OpenAPI確保所擷取的憑據處於可用狀態。
package main
import (
"fmt"
"log"
"os"
"sync"
"time"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
ecs20140526 "github.com/alibabacloud-go/ecs-20140526/v7/client"
util "github.com/alibabacloud-go/tea-utils/v2/service"
"github.com/alibabacloud-go/tea/tea"
"github.com/aliyun/credentials-go/credentials"
)
// Credential 單例結構體,用於管理阿里雲憑證執行個體
type Credential struct {
instance credentials.Credential
once sync.Once
}
var credentialInstance = &Credential{}
func GetCredentialInstance() credentials.Credential {
credentialInstance.once.Do(func() {
cfg := &credentials.Config{
Type: tea.String("ram_role_arn"),
AccessKeyId: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")),
AccessKeySecret: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")),
RoleArn: tea.String(os.Getenv("ALIBABA_CLOUD_ROLE_ARN")),
RoleSessionName: tea.String("RamRoleArnTest"),
RoleSessionExpiration: tea.Int(3600),
}
var err error
credentialInstance.instance, err = credentials.NewCredential(cfg)
if err != nil {
log.Fatalf("Credential initialization failed: %v", err)
}
})
return credentialInstance.instance
}
// EcsClient 單例結構體,用於管理 ECS 用戶端執行個體
type EcsClient struct {
instance *ecs20140526.Client
once sync.Once
}
var ecsClientInstance = &EcsClient{}
func GetEcsClientInstance(cred credentials.Credential) *ecs20140526.Client {
ecsClientInstance.once.Do(func() {
cfg := &openapi.Config{
Endpoint: tea.String("ecs.cn-hangzhou.aliyuncs.com"),
Credential: cred,
}
var err error
ecsClientInstance.instance, err = ecs20140526.NewClient(cfg)
if err != nil {
log.Fatalf("ECS client initialization failed: %v", err)
}
})
return ecsClientInstance.instance
}
// 執行主任務
func runTask() {
cred := GetCredentialInstance()
credentialModel, err := cred.GetCredential()
if err != nil {
log.Printf("Failed to get credential: %v", err)
return
}
fmt.Println(time.Now())
fmt.Printf("AK ID: %s, AK Secret: %s, STS Token: %s\n",
*credentialModel.AccessKeyId,
*credentialModel.AccessKeySecret,
*credentialModel.SecurityToken)
ecsClient := GetEcsClientInstance(cred)
req := &ecs20140526.DescribeRegionsRequest{}
runtime := &util.RuntimeOptions{}
resp, err := ecsClient.DescribeRegionsWithOptions(req, runtime)
if err != nil {
log.Printf("ECS API call failed: %v", err)
return
}
fmt.Printf("Invoke result: %d\n", *resp.StatusCode)
}
func main() {
done := make(chan bool)
// 啟動一個 goroutine 來執行定時任務
go func() {
tick := time.NewTicker(1 * time.Second)
defer tick.Stop()
executionCount := 0
delays := []time.Duration{0, 600, 3600, 100} // 延遲時間(秒)
for {
select {
case <-tick.C:
if executionCount < len(delays) {
delay := delays[executionCount]
time.Sleep(delay * time.Second)
runTask()
executionCount++
} else {
close(done)
return
}
}
}
}()
<-done
fmt.Println("All tasks completed. Exiting...")
}

根據日誌顯示結果進行分析:
在第一次調用時,由於未緩衝憑據資訊,系統根據配置擷取憑據資訊。擷取到憑據後,憑據資訊被儲存在緩衝中。
第二次調用所使用的憑據資訊與第一次相同,表明第二次調用是從緩衝中提取的憑據資訊。
第三次調用時,由於憑據的到期時間(RoleSessionExpiration)被設定為3600秒,而第三次調用發生在第一次調用之後的4200秒,此時緩衝中的憑據已到期。因此,SDK依據自動重新整理機制重新擷取了新的憑據資訊,並將新擷取的憑據資訊再次儲存於緩衝中。
第四次調用所使用的憑據資訊與第三次重新擷取的憑據資訊一致,這表明緩衝中的憑據在到期後已被更新為新的憑據。
相關文檔
RAM相關的基本概念,請參見基本概念。
如何建立AccessKey,請參見建立AccessKey。
如何通過程式方式建立RAM使用者、AccessKey、RAM角色、權限原則及進行授權等操作,請參見RAM SDK概覽。
如何通過程式方式進行角色扮演,請參見STS SDK概覽。
關於RAM及STS相關的API資訊,請參見API參考。