在使用阿里雲SDK時,憑據資訊(例如AccessKey、STS Token等)由Credentials工具統一管理。本文將為您介紹Credentials工具支援的憑據類型及其配置方法,協助您快速掌握Credentials工具的使用。
前提條件
使用Credentials工具需要Java 8或更高版本,詳見阿里雲SDK支援策略。
使用V2.0代系的阿里雲SDK,請參見V2.0 SDK 和 V1.0 SDK。
安裝Credentials工具
請使用最新發行的Credentials依賴包,以確保對所有功能的支援。
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>credentials-java</artifactId>
<version>latest-version</version>
</dependency>
<!-- 若單獨使用credentials-java時,需額外引入tea包 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea</artifactId>
<version>latest-version</version>
</dependency>Credentials依賴包的最新版本資訊,請查閱GitHub或Maven Repository;tea依賴包的最新版本資訊,請查閱GitHub或Maven Repository。
Credentials工具支援的憑據類型及其配置參數
Credentials工具支援的憑據類型及其配置參數均在com.aliyun.credentials.models.Config中定義。憑據類型由參數type指定,不同的憑據類型所需的配置參數各不相同。下表將詳細介紹type的取值範圍及其支援的配置參數,其中,表示必填參數,-表示選擇性參數,表示不支援參數。
未在下表中列出的憑據類型及參數表示不建議繼續使用。
type | |||||||
accessKeyId:訪問憑據ID。 | |||||||
accessKeySecret:訪問憑據密鑰。 | |||||||
securityToken:STS Token。 | - | ||||||
roleArn:RAM角色的ARN。 | |||||||
roleSessionName:自訂會話名稱,預設格式為 | - | - | |||||
roleName:RAM角色名稱。 | - | ||||||
disableIMDSv1:是否強制使用加固模式,預設值為 | - | ||||||
bearerToken:bearer token。 | |||||||
policy:自訂權限原則。 | - | - | |||||
roleSessionExpiration:會話到期時間,預設3600秒。最小值為900秒,最大值為RAM角色支援的最大會話時間。 | - | - | |||||
oidcProviderArn:OIDC身份供應商ARN。 | |||||||
oidcTokenFilePath:OIDC Token檔案路徑。 | |||||||
externalId:角色外部 ID,主要功能是防止混淆代理人問題。更多資訊,請參見使用ExternalId防止混淆代理人問題。 | - | ||||||
credentialsURI:外部憑據的URI。 | |||||||
STSEndpoint:STS的服務存取點,支援VPC服務存取點和公網服務存取點,可選的值請參見服務存取點,預設值為 | - | - | |||||
timeout:請求的讀逾時時間,預設值為5000毫秒。 | - | - | - | - | |||
connectTimeout:請求的連線逾時時間,預設值為10000毫秒。 | - | - | - | - |
使用Credentials工具
前文已介紹Credentials工具所支援的憑據類型及其配置參數,接下來將通過詳細的程式碼範例進一步說明,您可以根據具體情況選擇適合的使用方式。
在專案中使用明文AccessKey,容易因代碼倉庫許可權管理不當造成AccessKey泄露,會威脅該帳號下所有資源的安全。建議通過環境變數、設定檔等方式儲存AccessKey。
在使用Credentials工具時,建議採用單例模式。這一做法能夠啟用Credentials工具內建的憑據緩衝功能,有效防止因多次調用介面而導致的限流問題,以及因建立多個執行個體而引起的資源浪費問題。詳細資料請參見Session類型憑據自動重新整理機制。
方式一:預設憑據鏈
該方式是OpenAPI門戶範例程式碼中預設採用的方式。
在使用Credentials工具時,如果不傳入任何配置參數,Credentials工具將從預設憑據鏈中擷取憑據,並將所獲得的憑據作為訪問憑據。在採用此方式時,必須確保在應用程式運行環境中已配置預設憑據鏈所支援的任意一種憑據擷取方式。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) throws Exception {
// 不指定配置參數,將從預設憑據鏈中擷取憑據。
Client credentialClient = new Client();
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// 若使用雲產品 V2.0 SDK 時,使用com.aliyun.teaopenapi.models.Config傳遞credential
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// 省略使用 config 初始化雲產品 client 的代碼...
}
}方式二:AK
Credentials工具將使用您提供的AccessKey作為訪問憑據。
阿里雲帳號(主帳號)擁有資源的全部許可權,AK一旦泄露,會給系統帶來巨大風險,不建議使用。
推薦使用最小化授權的RAM使用者的AK。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("access_key");
// 必填參數,此處以從環境變數中擷取AccessKey ID為例
credentialConfig.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
// 必填參數,此處以從環境變數中擷取AccessKey Secret為例
credentialConfig.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
Client credentialClient = new Client(credentialConfig);
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// 若使用雲產品 V2.0 SDK 時,使用com.aliyun.teaopenapi.models.Config傳遞credential
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// 省略使用 config 初始化雲產品 client 的代碼...
}
}方式三:STS Token
Credentials工具將使用您提供的靜態STS Token作為訪問憑據。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) {
Config credentialConfig = new Config();
credentialConfig.setType("sts");
// 必填參數,此處以從環境變數中擷取AccessKey ID為例
credentialConfig.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
// 必填參數,此處以從環境變數中擷取AccessKey Secret為例
credentialConfig.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// 必填參數,此處以從環境變數中擷取臨時SecurityToken為例
credentialConfig.setSecurityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN"));
Client credentialClient = new Client(credentialConfig);
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// 若使用雲產品 V2.0 SDK 時,使用com.aliyun.teaopenapi.models.Config傳遞credential
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// 省略使用 config 初始化雲產品 client 的代碼...
}
}方式四:AK及RamRoleArn
Credentials工具將使用您提供的AK及RAM角色ARN調用AssumeRole擷取STS Token,並將該STS Token作為訪問憑據。通過此方式擷取的憑據支援自動重新整理,詳情請參見Session類型憑據自動重新整理機制。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("ram_role_arn");
// 必填參數,此處以從環境變數中擷取AccessKey ID為例
credentialConfig.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
// 必填參數,此處以從環境變數中擷取AccessKey Secret為例
credentialConfig.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// 選擇性參數,支援使用臨時憑據繼續扮演其他RAM角色。
credentialConfig.setSecurityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN"));
// 必填參數,要扮演的RAM角色ARN,樣本值:acs:ram::123456789012****:role/adminrole。支援通過環境變數ALIBABA_CLOUD_ROLE_ARN設定。
credentialConfig.setRoleArn("<RoleArn>");
// 選擇性參數,角色會話名稱,預設格式為:credentials-java-目前時間的時間戳記。支援通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定。
credentialConfig.setRoleSessionName("<RoleSessionName>");
// 選擇性參數,設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}。
credentialConfig.setPolicy("<Policy>");
// 選擇性參數,角色外部ID,主要功能是防止混淆代理人問題。
credentialConfig.setExternalId("<ExternalId>");
// 選擇性參數,會話到期時間,預設3600秒。
credentialConfig.setRoleSessionExpiration(3600);
Client credentialClient = new Client(credentialConfig);
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// 若使用雲產品 V2.0 SDK 時,使用com.aliyun.teaopenapi.models.Config傳遞credential
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// 省略使用 config 初始化雲產品 client 的代碼...
}
}方式五:ECS執行個體RAM角色
若您的應用程式運行於ECS或ECI執行個體,並且執行個體已被授予RAM角色,Credentials工具支援通過執行個體中繼資料擷取該RAM角色的STS Token作為訪問憑據。在訪問執行個體中繼資料時,程式會首先擷取授予給當前執行個體的RAM角色名稱,然後再基於該角色擷取對應的STS Token。您可以通過參數roleName或環境變數 ALIBABA_CLOUD_ECS_METADATA 指定RAM角色名稱,從而減少擷取憑據所需的時間,提升效率。通過此方式擷取的憑據支援自動重新整理,詳情請參見Session類型憑據自動重新整理機制。
Credentials工具將預設採用加固模式(IMDSv2)訪問執行個體中繼資料。若在加固模式下發生異常,您可以通過參數disableIMDSv1或環境變數 ALIBABA_CLOUD_IMDSV1_DISABLED 來控制異常處理邏輯:
當值為
false(預設)時,系統將嘗試切換到普通模式繼續擷取憑據;當值為
true時,表示僅允許使用加固模式擷取憑據,若加固模式訪問失敗則會拋出異常。
服務端是否支援IMDSv2,取決於您在伺服器的配置。
另外,您可以通過配置環境變數ALIBABA_CLOUD_ECS_METADATA_DISABLED=true來關閉執行個體中繼資料的憑據訪問。
關於執行個體中繼資料的介紹,請參見執行個體中繼資料。
如何為ECS或ECI執行個體授予RAM角色,具體操作請參見建立RAM角色並授予給ECS執行個體和為ECI執行個體授予執行個體RAM角色。
使用加固模式擷取臨時身份憑據時,credentials-java的版本不低於0.3.10。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("ecs_ram_role");
// 選擇性參數,該ECS被授予的RAM角色的角色名稱,不填會自動擷取,建議加上以減少請求次數。支援通過環境變數ALIBABA_CLOUD_ECS_METADATA設定。
credentialConfig.setRoleName("<RoleName>");
// 選擇性參數,true表示強制使用加固模式。預設值:false,系統將首先嘗試在加固模式下擷取憑據。如果失敗,則會切換到普通模式進行嘗試。
credentialConfig.setDisableIMDSv1(false);
Client credentialClient = new Client(credentialConfig);
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// 若使用雲產品 V2.0 SDK 時,使用com.aliyun.teaopenapi.models.Config傳遞credential
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// 省略使用 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訪問阿里雲相關服務。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("oidc_role_arn");
// 必填參數,RAM角色ARN,支援通過環境變數ALIBABA_CLOUD_ROLE_ARN設定。
credentialConfig.setRoleArn("<RoleArn>");
// 必填參數,OIDC身份供應商ARN,支援通過環境變數ALIBABA_CLOUD_OIDC_PROVIDER_ARN設定。
credentialConfig.setOidcProviderArn("<OidcProviderArn>");
// 必填參數,OIDC Token檔案路徑,支援通過環境變數ALIBABA_CLOUD_OIDC_TOKEN_FILE設定。
credentialConfig.setOidcTokenFilePath("<OidcTokenFilePath>");
// 選擇性參數,角色會話名稱,支援通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定。
credentialConfig.setRoleSessionName("<RoleSessionName>");
// 選擇性參數,設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
credentialConfig.setPolicy("<Policy>");
// 選擇性參數,session到期時間,預設值3600毫秒。
credentialConfig.setRoleSessionExpiration(3600);
Client credentialClient = new Client(credentialConfig);
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// 若使用雲產品 V2.0 SDK 時,使用com.aliyun.teaopenapi.models.Config傳遞credential
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// 省略使用 config 初始化雲產品 client 的代碼...
}
}方式七:URI憑據
通過封裝STS服務並對外暴露服務的URI,外部服務能夠通過該URI擷取STS Token,從而有效降低AK等敏感資訊的暴露風險。Credentials工具支援通過訪問您所提供的URI來擷取STS Token,並將該STS Token作為訪問憑據。通過此方式擷取的憑據支援自動重新整理,詳情請參見Session類型憑據自動重新整理機制。
該URI必須滿足如下條件:
支援GET請求。
響應狀態代碼為2XX。
響應體為如下的結構:
{ "Code": "Success", "AccessKeySecret": "yourAccessKeySecret", "AccessKeyId": "STS.****************", "Expiration": "2021-09-26T03:46:38Z", "SecurityToken": "yourSecurityToken" }
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("credentials_uri");
// 必填參數,外部擷取憑據的URI,格式為http://local_or_remote_uri/,支援通過環境變數ALIBABA_CLOUD_CREDENTIALS_URI設定。
credentialConfig.setCredentialsUri("<CredentialsUri>");
Client credentialClient = new Client(credentialConfig);
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// 若使用雲產品 V2.0 SDK 時,使用com.aliyun.teaopenapi.models.Config傳遞credential
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// 省略使用 config 初始化雲產品 client 的代碼...
}
}方式八:Bearer Token
目前只有Cloud Call CenterCCC這款產品支援Bearer Token。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("bearer");
// 必填參數,填入您的Bearer Token
credentialConfig.setBearerToken("<BearerToken>");
Client credentialClient = new Client(credentialConfig);
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// 若使用CCC V2.0 SDK 時,使用com.aliyun.teaopenapi.models.Config傳遞credential
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// 省略使用 config 初始化雲產品 client 內容...
}
}預設憑據鏈
預設憑據鏈是一種兜底策略,按照內建的憑據尋找順序逐層向下尋找,直至擷取憑據資訊。若所有情況均未成功擷取到憑據資訊,則會拋出CredentialException。以下為尋找順序:
1. 使用系統屬性
Credentials工具會優先在系統屬性中擷取憑據資訊。
當在系統屬性中定義了alibabacloud.accessKeyId、alibabacloud.accessKeySecret時,使用AK作為預設憑據。
當在系統屬性中定義了alibabacloud.accessKeyId、alibabacloud.accessKeySecret及alibabacloud.sessionToken時,使用STS Token作為預設憑據。
您可以通過運行Java程式時添加如下JVM參數指定這些值:
-Dalibabacloud.accessKeyId=your-access-key-id -Dalibabacloud.accessKeySecret=your-access-key-secret
2. 使用環境變數
如果未找到系統屬性中的憑據資訊,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作為預設憑據。
3. 使用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作為預設憑據。
4. 使用config.json設定檔
該功能要求credentials-java的版本不低於0.3.8。
如果仍未擷取到憑據資訊,Credentials工具會嘗試從預設路徑載入config.json設定檔,並擷取指定的憑據作為預設憑據。該檔案的預設完整路徑如下:
Linux/Mac:
~/.aliyun/config.jsonWindows:
C:\Users\USER_NAME\.aliyun\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
}
]
}
參數名稱 | 參數介紹 |
current | 指定憑據名稱以擷取相應的憑據配置資訊,其值為 |
profiles | 憑據資訊集合。通過參數
|
5. 使用執行個體RAM角色
如果仍未擷取到憑據資訊,Credentials將嘗試通過執行個體中繼資料擷取授予給該執行個體的RAM角色的STS Token,並將其作為預設憑據。在訪問執行個體中繼資料時,程式會首先擷取授予給當前執行個體的RAM角色名稱,然後再基於該角色擷取對應的STS Token。您也可以通過環境變數 ALIBABA_CLOUD_ECS_METADATA 指定RAM角色名稱,從而減少憑據擷取所需的時間,提升效率。
預設情況下,Credentials 會使用加固模式(IMDSv2)訪問中繼資料。若在加固模式下發生異常,您可以通過環境變數 ALIBABA_CLOUD_IMDSV1_DISABLED 來控制異常處理邏輯:
當值為
false(預設)時,系統將嘗試切換到普通模式繼續擷取憑據;當值為
true時,表示僅允許使用加固模式擷取憑據,若加固模式訪問失敗則會拋出異常。
另外,您可以通過配置環境變數ALIBABA_CLOUD_ECS_METADATA_DISABLED=true來關閉ECS中繼資料的憑據訪問。
關於執行個體中繼資料的介紹,請參見執行個體中繼資料。
如何為ECS或ECI執行個體授予RAM角色,具體操作請參見建立RAM角色並授予給ECS執行個體和為ECI執行個體授予執行個體RAM角色。
使用加固模式擷取臨時身份憑據時,要求
credentials-java的版本不低於0.3.10。
6. 使用CredentialsURI
如果仍未擷取到憑據資訊,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確保所擷取的憑據處於可用狀態。
import com.aliyun.credentials.models.CredentialModel;
import com.aliyun.ecs20140526.Client;
import com.aliyun.ecs20140526.models.DescribeRegionsRequest;
import com.aliyun.ecs20140526.models.DescribeRegionsResponse;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import java.util.Date;
import java.util.concurrent.*;
public class Sample {
/**
* Credential類用於管理阿里雲憑據執行個體,採用單例模式。
*/
private static class Credential {
private static volatile com.aliyun.credentials.Client instance;
private Credential() {
}
public static com.aliyun.credentials.Client getInstance() {
if (instance == null) {
synchronized (Credential.class) {
if (instance == null) {
try {
com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config();
config.setType("ram_role_arn");
config.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
config.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
config.setRoleArn(System.getenv("ALIBABA_CLOUD_ROLE_ARN"));
config.setRoleSessionName("RamRoleArnTest");
config.setRoleSessionExpiration(3600);
instance = new com.aliyun.credentials.Client(config);
} catch (Exception e) {
throw new RuntimeException("Credential initialization failed: " + e.getMessage(), e);
}
}
}
}
return instance;
}
}
/**
* EcsClient類用於管理ECS用戶端,採用單例模式。
*/
private static class EcsClient {
private static volatile Client instance;
private EcsClient() {
}
public static Client getInstance(com.aliyun.credentials.Client credentialClient) {
if (instance == null) {
synchronized (EcsClient.class) {
if (instance == null) {
try {
Config ecsConfig = new Config();
ecsConfig.setEndpoint("ecs.cn-hangzhou.aliyuncs.com");
ecsConfig.setCredential(credentialClient);
instance = new Client(ecsConfig);
} catch (Exception e) {
throw new RuntimeException("ECS client initialization failed: " + e.getMessage(), e);
}
}
}
}
return instance;
}
}
public static void main(String[] args) {
// 使用ThreadPoolExecutor建立定時線程池
ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(
1,
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
scheduler.setKeepAliveTime(0L, TimeUnit.SECONDS);
scheduler.allowCoreThreadTimeOut(false); // 不允許核心線程逾時
// 定義一個 Runnable 任務來執行調用邏輯
Runnable task = () -> {
try {
com.aliyun.credentials.Client credentialClient = Credential.getInstance();
CredentialModel credential = credentialClient.getCredential();
System.out.println(new Date());
System.out.printf("AK ID:%s, AK Secret:%s, STS Token:%s%n", credential.accessKeyId, credential.accessKeySecret, credential.securityToken);
// 這裡以調用ECS介面為例驗證憑據是否可用,您可根據實際情況修改
Client ecsClient = EcsClient.getInstance(credentialClient);
DescribeRegionsRequest request = new DescribeRegionsRequest();
RuntimeOptions runtime = new RuntimeOptions();
DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(request, runtime);
System.out.printf("Invoke result:%s%n", response.statusCode);
} catch (Exception e) {
throw new RuntimeException("ECS client execution failed: " + e.getMessage(), e);
}
};
try {
// 第一次執行任務(立即執行)
scheduler.execute(task);
// 第二次執行任務,延遲600秒後執行
scheduler.schedule(task, 600, TimeUnit.SECONDS);
// 第三次執行任務,在第二次基礎上再延遲3600秒後執行
scheduler.schedule(task, 4200, TimeUnit.SECONDS);
// 第四次執行任務,在第三次基礎上再延遲100秒後執行
scheduler.schedule(task, 4300, TimeUnit.SECONDS);
} finally {
// 關閉線程池,確保所有任務完成後關閉
scheduler.shutdown();
try {
if (!scheduler.awaitTermination(4500, TimeUnit.SECONDS)) {
scheduler.shutdownNow();
}
} catch (InterruptedException e) {
scheduler.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
}
根據日誌顯示結果進行分析:
在第一次調用時,由於未緩衝憑據資訊,系統根據配置擷取憑據資訊。擷取到憑據後,憑據資訊被儲存在緩衝中。
第二次調用所使用的憑據資訊與第一次相同,表明第二次調用是從緩衝中提取的憑據資訊。
第三次調用時,由於憑據的到期時間(RoleSessionExpiration)被設定為3600秒,而第三次調用發生在第一次調用之後的4200秒,此時緩衝中的憑據已到期。因此,SDK依據自動重新整理機制重新擷取了新的憑據資訊,並將新擷取的憑據資訊再次儲存於緩衝中。
第四次調用所使用的憑據資訊與第三次重新擷取的憑據資訊一致,這表明緩衝中的憑據在到期後已被更新為新的憑據。
相關文檔
RAM相關的基本概念,請參見基本概念。
如何建立AccessKey,請參見建立AccessKey。
如何通過程式方式建立RAM使用者、AccessKey、RAM角色、權限原則及進行授權等操作,請參見RAM SDK概覽。
如何通過程式方式進行角色扮演,請參見STS SDK概覽。
關於RAM及STS相關的API資訊,請參見API參考。