管理訪問憑據(jù)
本文中含有需要您注意的重要提示信息,忽略該信息可能對您的業(yè)務造成影響,請務必仔細閱讀。
當您通過阿里云SDK調(diào)用OpenAPI進行資源操作時,必須正確配置憑證信息。阿里云的Credentials工具提供了一套強大的功能,使您能夠輕松地獲取和管理這些訪問憑證。無論是利用默認憑證,AccessKey(AK),還是安全令牌服務(STS)令牌等,Credentials工具都能為您提供相應支持。此外,本文檔將詳細闡述如何根據(jù)優(yōu)先級使用默認憑證。您將深入理解如何在阿里云SDK中配置和維護憑證,從而確保您對云資源的操作既有效率又具有高度安全性。
背景信息
憑據(jù)是指用戶證明其身份的一組信息。用戶在系統(tǒng)中進行登錄時,需要提供正確的憑據(jù)才能驗證身份。常見的憑據(jù)類型有:
阿里云主賬號和RAM用戶的永久憑據(jù) AccessKey(簡稱AK)是由AccessKey ID和AccessKey Secret組成的密鑰對。
阿里云RAM角色的STS臨時訪問Token,簡稱STS Token。它是可以自定義時效和訪問權限的臨時身份憑據(jù),詳情請參見什么是STS。
Bearer Token。它是一種身份驗證和授權的令牌類型。
前提條件
使用Credentials工具最低要求是Java 8(JDK 1.8)。
使用V2.0代系的阿里云SDK,請參見通過IDE使用阿里云Java SDK。
安裝Credentials工具
Maven安裝方式。
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>credentials-java</artifactId>
<version>LATEST</version>
</dependency>
使用最新發(fā)布Credentials依賴包,確保所有憑證支持。
請查看ChangeLog.txt獲取所有已發(fā)布的版本列表。
建議優(yōu)先選用阿里云V2.0 SDK。如果選擇不使用阿里云V2.0 SDK,而是單獨依賴credentials-java,則務必引入下面的依賴,否則將出現(xiàn)錯誤,無法找到com.aliyun.tea.TeaModel類文件。
<dependency> <groupId>com.aliyun</groupId> <artifactId>tea</artifactId> <version>LATEST</version> </dependency>
初始化憑據(jù)客戶端
Credentials工具支持多種方式初始化憑據(jù)客戶端,您可根據(jù)實際情況選擇合適的方式進行憑據(jù)客戶端初始化。
在項目中使用明文AccessKey,容易因代碼倉庫權限管理不當造成AccessKey泄露,會威脅該賬號下所有資源的安全。建議通過環(huán)境變量、配置文件等方式獲取AccessKey。
方式一:使用默認憑據(jù)鏈
當您在初始化憑據(jù)客戶端不傳入任何參數(shù)時,Credentials工具會使用默認憑據(jù)鏈方式初始化客戶端。默認憑據(jù)的讀取邏輯請參見默認憑據(jù)鏈。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
public class DemoTest {
public static void main(String[] args) throws Exception{
// 不指定參數(shù)
Config credentialConfig = new Config();
Client credentialClient = new Client(credentialConfig);
}
}
接口調(diào)用方法
通過默認憑據(jù)提供鏈自動創(chuàng)建訪問憑證,并在不使用硬編碼AccessKey的情況下成功調(diào)用云產(chǎn)品OpenAPI接口。
本示例以調(diào)用云服務器ECS的DescribeRegions接口為例,因此需先安裝ECS SDK。
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;
public class Sample {
public static void main(String[] args) throws Exception {
// 使用默認憑證初始化Credentials Client。
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client();
Config ecsConfig = new Config();
// 配置云產(chǎn)品服務接入地址(endpoint)。
ecsConfig.setEndpoint("ecs.aliyuncs.com");
// 使用 Credentials 配置憑證。
ecsConfig.setCredential(credentialClient);
// 初始化 ECS Client。
Client ecsClient = new Client(ecsConfig);
// 初始化 DescribeRegions 請求。
DescribeRegionsRequest describeInstancesRequest = new DescribeRegionsRequest();
// 初始化運行時配置。
RuntimeOptions runtime = new RuntimeOptions();
// 調(diào)用 DescribeRegions 接口并獲得響應。
DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, runtime);
System.out.println(response.body.toMap());
}
}
方式二:使用AK
阿里云賬號、RAM用戶可生成調(diào)用OpenAPI的密鑰對AK。如何獲取AK請參見文檔創(chuàng)建AccessKey。您可使用AK初始化憑據(jù)客戶端。
阿里云主賬號擁有資源的全部權限,AK一旦泄露,會給系統(tǒng)帶來巨大風險,不建議使用。
推薦使用最小化授權的RAM用戶的AK。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
public class DemoTest {
public static void main(String[] args) throws Exception{
Config credentialConfig = new Config();
credentialConfig.setType("access_key");
credentialConfig.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
credentialConfig.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
Client credentialClient = new Client(credentialConfig);
}
}
接口調(diào)用方法
通過Credentials工具讀取AK,完成云產(chǎn)品OpenAPI接口的調(diào)用。
本示例以調(diào)用云服務器ECS的DescribeRegions接口為例,因此需先安裝ECS SDK。
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;
public class Sample {
public static void main(String[] args) throws Exception {
// 使用AK 初始化Credentials Client。
com.aliyun.credentials.models.Config credentialsConfig = new com.aliyun.credentials.models.Config();
// 憑證類型。
credentialsConfig.setType("access_key");
// 設置為AccessKey ID值。
credentialsConfig.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
// 設置為AccessKey Secret值。
credentialsConfig.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialsConfig);
Config ecsConfig = new Config();
// 配置云產(chǎn)品服務接入地址(endpoint)。
ecsConfig.setEndpoint("ecs.aliyuncs.com");
// 使用Credentials配置憑證。
ecsConfig.setCredential(credentialClient);
// 初始化ECS Client。
Client ecsClient = new Client(ecsConfig);
// 初始化DescribeRegions請求。
DescribeRegionsRequest describeInstancesRequest = new DescribeRegionsRequest();
// 初始化運行時配置。
RuntimeOptions runtime = new RuntimeOptions();
// 調(diào)用DescribeRegions接口并獲得響應。
DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, runtime);
System.out.println(response.body.toMap());
}
}
方式三:使用STS Token
以一個RAM用戶的身份調(diào)用STS服務的AssumeRole接口,設置Token的最大過期時間,即可換取到臨時憑據(jù)STS Token。以下示例演示如何使用STS Token初始化憑據(jù)客戶端(不包含如何獲取到STS Token的過程)。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
public class DemoTest {
public static void main(String[] args) {
Config credentialConfig = new Config();
credentialConfig.setType("sts");
// 從環(huán)境變量中獲取AccessKey ID的值
credentialConfig.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
// 從環(huán)境變量中獲取AccessKeySecret的值
credentialConfig.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// 從環(huán)境變量中獲取臨時SecurityToken的值
credentialConfig.setSecurityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN"));
Client credentialClient = new Client(credentialConfig);
}
}
接口調(diào)用方法
通過Credentials工具讀取臨時安全令牌(STS Token),完成云產(chǎn)品OpenAPI接口的調(diào)用。
本示例以調(diào)用云服務器ECS的DescribeRegions接口為例,因此需先安裝ECS SDK和STS SDK。
import com.aliyun.ecs20140526.models.DescribeRegionsRequest;
import com.aliyun.ecs20140526.models.DescribeRegionsResponse;
import com.aliyun.sts20150401.Client;
import com.aliyun.sts20150401.models.AssumeRoleRequest;
import com.aliyun.sts20150401.models.AssumeRoleResponse;
import com.aliyun.sts20150401.models.AssumeRoleResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
public class Sample {
public static void main(String[] args) throws Exception {
// 創(chuàng)建StsClient對象,并調(diào)用assumeRole服務獲取STS Token
Config config = new Config()
// 從環(huán)境變量中獲取AccessKey ID的值
.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
// 從環(huán)境變量中獲取AccessKey Secret的值
.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
config.endpoint = "sts.cn-hangzhou.aliyuncs.com";
Client client = new Client(config);
AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest()
// 要扮演的RAM角色ARN,示例值:acs:ram::123456789012****:role/adminrole,可以通過環(huán)境變量ALIBABA_CLOUD_ROLE_ARN設置RoleArn
.setRoleArn("<RoleArn>")
// 角色會話名稱,可以通過環(huán)境變量ALIBABA_CLOUD_ROLE_SESSION_NAME設置RoleSessionName
.setRoleSessionName("<RoleSessionName>");
RuntimeOptions runtime = new RuntimeOptions();
AssumeRoleResponse assumeRoleResponse = client.assumeRoleWithOptions(assumeRoleRequest, runtime);
AssumeRoleResponseBody.AssumeRoleResponseBodyCredentials assumeRoleResponseBodyCredentials = assumeRoleResponse.body.credentials;
// 使用STS Token初始化Credentials Client。
com.aliyun.credentials.models.Config credentialsConfig = new com.aliyun.credentials.models.Config();
credentialsConfig.setType("sts"); // 憑證類型。
credentialsConfig.setAccessKeyId(assumeRoleResponseBodyCredentials.accessKeyId);
credentialsConfig.setAccessKeySecret(assumeRoleResponseBodyCredentials.accessKeySecret);
credentialsConfig.setSecurityToken(assumeRoleResponseBodyCredentials.securityToken);
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialsConfig);
// 使用Credentials創(chuàng)建ecs client。
Config ecsConfig = new Config();
ecsConfig.setEndpoint("ecs.aliyuncs.com");
ecsConfig.setCredential(credentialClient);
com.aliyun.ecs20140526.Client ecsClient = new com.aliyun.ecs20140526.Client(ecsConfig);
DescribeRegionsRequest describeInstancesRequest = new DescribeRegionsRequest();
RuntimeOptions describeRegionsRuntime = new RuntimeOptions();
// 調(diào)用DescribeRegions接口并獲得響應。
DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, describeRegionsRuntime);
System.out.println(response.body.toMap());
}
}
方式四:使用AK及RamRoleArn
該方式底層實現(xiàn)是STS Token。通過指定RAM角色的ARN(Alibabacloud Resource Name),Credentials工具可以幫助開發(fā)者前往STS換取STS Token。您也可調(diào)用setPolicy
函數(shù)限制RAM角色到一個更小的權限集合。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("ram_role_arn");
credentialConfig.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
credentialConfig.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// 要扮演的RAM角色ARN,示例值:acs:ram::123456789012****:role/adminrole,可以通過環(huán)境變量ALIBABA_CLOUD_ROLE_ARN設置RoleArn
credentialConfig.setRoleArn("<RoleArn>");
// 角色會話名稱,可以通過環(huán)境變量ALIBABA_CLOUD_ROLE_SESSION_NAME設置RoleSessionName
credentialConfig.setRoleSessionName("<RoleSessionName>");
// 設置更小的權限策略,非必填。示例值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
credentialConfig.setPolicy("<Policy>");
// Not required, the external ID of the RAM role
// This parameter is provided by an external party and is used to prevent the confused deputy problem.
credentialConfig.setExternalId("<ExternalId>");
credentialConfig.setRoleSessionExpiration(3600);
Client credentialClient = new Client(credentialConfig);
}
}
接口調(diào)用方法
本示例以調(diào)用云服務器ECS的DescribeRegions接口為例,因此需先安裝ECS SDK。
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;
public class Sample {
public static void main(String[] args) throws Exception {
// 使用RamRoleArn初始化Credentials Client
com.aliyun.credentials.models.Config credentialsConfig = new com.aliyun.credentials.models.Config();
// 憑證類型
credentialsConfig.setType("ram_role_arn");
// 從環(huán)境變量中獲取AccessKey ID的值
credentialsConfig.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
// 從環(huán)境變量中獲取AccessKey Secret的值
credentialsConfig.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// 要扮演的RAM角色ARN,示例值:acs:ram::123456789012****:role/adminrole,可以通過環(huán)境變量ALIBABA_CLOUD_ROLE_ARN設置RoleArn
credentialsConfig.setRoleArn("<RoleArn>");
// 角色會話名稱,可以通過環(huán)境變量ALIBABA_CLOUD_ROLE_SESSION_NAME設置RoleSessionName
credentialsConfig.setRoleSessionName("<RoleSessionName>");
// 設置更小的權限策略,非必填。示例值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
credentialsConfig.setPolicy("<Policy>");
// Not required, the external ID of the RAM role
// This parameter is provided by an external party and is used to prevent the confused deputy problem.
credentialsConfig.setExternalId("<ExternalId>");
// 會話有效時間
credentialsConfig.setRoleSessionExpiration(3600);
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialsConfig);
// 使用Credentials初始化ECS Client。
Config ecsConfig = new Config();
ecsConfig.setEndpoint("ecs.aliyuncs.com");
ecsConfig.setCredential(credentialClient);
Client ecsClient = new Client(ecsConfig);
DescribeRegionsRequest describeInstancesRequest = new DescribeRegionsRequest();
RuntimeOptions runtime = new RuntimeOptions();
// 調(diào)用DescribeRegions接口并獲得響應。
DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, runtime);
System.out.println(response.body.toMap());
}
}
方式五:使用ECS實例RAM角色
該方式底層實現(xiàn)是STS Token。Credentials工具會自動獲取ECS實例綁定的RAM角色,調(diào)用ECS的元數(shù)據(jù)服務(Meta Data Server)換取STS Token,完成憑據(jù)客戶端初始化。ECI實例,容器服務 Kubernetes 版的Worker節(jié)點均支持綁定實例RAM角色。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("ecs_ram_role");
// 選填,該ECS角色的角色名稱,不填會自動獲取,但是建議加上以減少請求次數(shù),可以通過環(huán)境變量ALIBABA_CLOUD_ECS_METADATA設置RoleName
credentialConfig.setRoleName("<RoleName>");
Client credentialClient = new Client(credentialConfig);
}
}
接口調(diào)用方法
本示例以調(diào)用云服務器ECS的DescribeRegions接口為例,因此需先安裝ECS SDK。
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;
public class Sample {
public static void main(String[] args) throws Exception {
// 使用 EcsRamRole 初始化Credentials Client。
com.aliyun.credentials.models.Config credentialsConfig = new com.aliyun.credentials.models.Config();
// 憑證類型。
credentialsConfig.setType("ecs_ram_role");
// 選填,該ECS角色的角色名稱,不填會自動獲取,但是建議加上以減少請求次數(shù),可以通過環(huán)境變量ALIBABA_CLOUD_ECS_METADATA設置RoleName
credentialsConfig.setRoleName("<RoleName>");
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialsConfig);
Config ecsConfig = new Config();
// 配置云產(chǎn)品服務接入地址(endpoint)。
ecsConfig.setEndpoint("ecs.aliyuncs.com");
// 使用Credentials配置憑證。
ecsConfig.setCredential(credentialClient);
// 初始化ECS Client。
Client ecsClient = new Client(ecsConfig);
// 初始化DescribeRegions請求。
DescribeRegionsRequest describeInstancesRequest = new DescribeRegionsRequest();
// 初始化運行時配置。
RuntimeOptions runtime = new RuntimeOptions();
// 調(diào)用DescribeRegions接口并獲得響應。
DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, runtime);
System.out.println(response.body.toMap());
}
}
方式六:使用OIDCRoleArn
在容器服務 Kubernetes 版中設置了Worker節(jié)點RAM角色后,對應節(jié)點內(nèi)的Pod中的應用也就可以像ECS上部署的應用一樣,通過元數(shù)據(jù)服務(Meta Data Server)獲取關聯(lián)角色的STS Token。但如果容器集群上部署的是不可信的應用(比如部署您的客戶提交的應用,代碼也沒有對您開放),您可能并不希望它們能通過元數(shù)據(jù)服務獲取Worker節(jié)點關聯(lián)實例RAM角色的STS Token。為了避免影響云上資源的安全,同時又能讓這些不可信的應用安全地獲取所需的 STS Token,實現(xiàn)應用級別的權限最小化,您可以使用RRSA(RAM Roles for Service Account)功能。阿里云容器集群會為不同的應用Pod創(chuàng)建和掛載相應的服務賬戶OIDC Token文件,并將相關配置信息注入到環(huán)境變量中,Credentials工具通過獲取環(huán)境變量的配置信息,調(diào)用STS服務的AssumeRoleWithOIDC - OIDC角色SSO時獲取扮演角色的臨時身份憑證接口換取綁定角色的STS Token。詳情請參見通過RRSA配置ServiceAccount的RAM權限實現(xiàn)Pod權限隔離。
注入的環(huán)境變量如下:
ALIBABA_CLOUD_ROLE_ARN:RAM角色名稱ARN;
ALIBABA_CLOUD_OIDC_PROVIDER_ARN:OIDC提供商ARN;
ALIBABA_CLOUD_OIDC_TOKEN_FILE:OIDC Token文件路徑;
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("oidc_role_arn");
// RAM角色名稱ARN,可以通過環(huán)境變量ALIBABA_CLOUD_ROLE_ARN設置RoleArn
credentialConfig.setRoleArn("<RoleArn>");
// OIDC提供商ARN,可以通過環(huán)境變量ALIBABA_CLOUD_OIDC_PROVIDER_ARN設置OidcProviderArn
credentialConfig.setOidcProviderArn("<OidcProviderArn>");
// OIDC Token文件路徑,可以通過環(huán)境變量ALIBABA_CLOUD_OIDC_TOKEN_FILE設置OidcTokenFilePath
credentialConfig.setOidcTokenFilePath("<OidcTokenFilePath>");
// 角色會話名稱,可以通過環(huán)境變量ALIBABA_CLOUD_ROLE_SESSION_NAME設置RoleSessionName
credentialConfig.setRoleSessionName("<RoleSessionName>");
// 設置更小的權限策略,非必填。示例值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
credentialConfig.setPolicy("<Policy>");
// 設置session過期時間
credentialConfig.setRoleSessionExpiration(3600);
Client credentialClient = new Client(credentialConfig);
}
}
接口調(diào)用方法
本示例以調(diào)用云服務器ECS的DescribeRegions接口為例,因此需先安裝ECS SDK。
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;
public class Sample {
public static void main(String[] args) throws Exception {
// 使用OIDCRoleArn初始化Credentials Client。
com.aliyun.credentials.models.Config credentialsConfig = new com.aliyun.credentials.models.Config();
// 憑證類型。
credentialsConfig.setType("oidc_role_arn");
// 角色ARN,可以通過環(huán)境變量ALIBABA_CLOUD_ROLE_ARN設置RoleArn
credentialConfig.setRoleArn("<RoleArn>");
// OIDC提供商ARN,可以通過環(huán)境變量ALIBABA_CLOUD_OIDC_PROVIDER_ARN設置OidcProviderArn
credentialConfig.setOidcProviderArn("<OidcProviderArn>");
// OIDC Token文件路徑,可以通過環(huán)境變量ALIBABA_CLOUD_OIDC_TOKEN_FILE設置OidcTokenFilePath
credentialConfig.setOidcTokenFilePath("<OidcTokenFilePath>");
// 角色會話名稱,可以通過環(huán)境變量ALIBABA_CLOUD_ROLE_SESSION_NAME設置RoleSessionName
credentialConfig.setRoleSessionName("<RoleSessionName>");
// 設置更小的權限策略,非必填。示例值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
credentialsConfig.setPolicy("<Policy>");
// 設置session過期時間
credentialsConfig.setRoleSessionExpiration(3600);
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialsConfig);
Config ecsConfig = new Config();
// 配置云產(chǎn)品服務接入地址(endpoint)。
ecsConfig.setEndpoint("ecs.aliyuncs.com");
// 使用Credentials配置憑證。
ecsConfig.setCredential(credentialClient);
// 初始化ECS Client。
Client ecsClient = new Client(ecsConfig);
// 初始化DescribeRegions請求。
DescribeRegionsRequest describeInstancesRequest = new DescribeRegionsRequest();
// 初始化運行時配置。
RuntimeOptions runtime = new RuntimeOptions();
// 調(diào)用DescribeRegions接口并獲得響應。
DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, runtime);
System.out.println(response.body.toMap());
}
}
方式七:使用URI憑據(jù)
該方案底層實現(xiàn)是STS Token。Credentials工具通過您提供的URI獲取STS Token,完成憑據(jù)客戶端初始化。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
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/,可以通過環(huán)境變量ALIBABA_CLOUD_CREDENTIALS_URI設置CredentialsUri
credentialConfig.setCredentialsUri("<CredentialsUri>");
Client credentialClient = new Client(credentialConfig);
}
}
接口調(diào)用方法
指定Credentials提供地址,實現(xiàn)通過本地或遠程的URI來獲取并自動更新Token,完成云產(chǎn)品接口的調(diào)用。
調(diào)用單個云產(chǎn)品的接口需要云產(chǎn)品依賴。本示例以調(diào)用云服務器ECS的DescribeRegions接口為例,因此需先安裝ECS SDK。
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;
public class Sample {
public static void main(String[] args) throws Exception {
// 使用URI憑據(jù)初始化Credentials Client。
com.aliyun.credentials.models.Config credentialsConfig = new com.aliyun.credentials.models.Config();
// 憑證類型。
credentialsConfig.setType("credentials_uri");
// 從環(huán)境變量獲取Credentials URI,格式為http://local_or_remote_uri/,可以通過環(huán)境變量ALIBABA_CLOUD_CREDENTIALS_URI設置CredentialsUri
credentialsConfig.setCredentialsUri("<CredentialsUri>");
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialsConfig);
Config ecsConfig = new Config();
// 配置云產(chǎn)品服務接入地址(endpoint)。
ecsConfig.setEndpoint("ecs.aliyuncs.com");
// 使用Credentials配置憑證。
ecsConfig.setCredential(credentialClient);
// 初始化ECS Client。
Client ecsClient = new Client(ecsConfig);
// 初始化DescribeRegions請求。
DescribeRegionsRequest describeInstancesRequest = new DescribeRegionsRequest();
// 初始化運行時配置。
RuntimeOptions runtime = new RuntimeOptions();
// 調(diào)用DescribeRegions接口并獲得響應。
DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, runtime);
System.out.println(response.body.toMap());
}
}
方式八:使用Bearer Token
目前只有云呼叫中心CCC這款產(chǎn)品支持Bearer Token的憑據(jù)初始化方式。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
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);
}
}
接口調(diào)用方法
本示例以調(diào)用呼叫中心CCC的GetInstance接口為例,因此需先安裝CCC SDK。
import com.aliyun.ccc20200701.Client;
import com.aliyun.ccc20200701.models.GetInstanceRequest;
import com.aliyun.ccc20200701.models.GetInstanceResponse;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
public class Sample {
public static void main(String[] args) throws Exception {
// 使用Bearer Token初始化Credentials Client。
com.aliyun.credentials.models.Config credentialsConfig = new com.aliyun.credentials.models.Config();
// 憑證類型。
credentialsConfig.setType("bearer");
// 服務器端自動生成的Bearer Token,帶有效期。
credentialsConfig.setBearerToken("<bearer_token>");
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialsConfig);
Config cccConfig = new Config();
// 配置云產(chǎn)品服務接入地址(endpoint)。
cccConfig.setEndpoint("ccc.aliyuncs.com");
// 使用Credentials配置憑證。
cccConfig.setCredential(credentialClient);
Client cccClient = new Client(cccConfig);
GetInstanceRequest getInstanceRequest = new GetInstanceRequest().setInstanceId("ccc-test");
// 初始化運行時配置。
RuntimeOptions runtime = new RuntimeOptions();
GetInstanceResponse response = cccClient.getInstanceWithOptions(getInstanceRequest, runtime);
System.out.println(response.body.toMap());
}
}
默認憑據(jù)鏈
當您的程序開發(fā)環(huán)境和生產(chǎn)環(huán)境采用不同的憑據(jù)類型,常見做法是在代碼中獲取當前環(huán)境信息,編寫獲取不同憑據(jù)的分支代碼。借助Credentials工具的默認憑據(jù)鏈,您可以用同一套代碼,通過程序之外的配置來控制不同環(huán)境下的憑據(jù)獲取方式。當您在不傳入?yún)?shù)的情況下,直接使用Client client = new Client()
初始化憑據(jù)客戶端時,阿里云SDK將會嘗試按照如下順序查找相關憑據(jù)信息。
1. 使用系統(tǒng)屬性
Credentials工具會優(yōu)先在系統(tǒng)屬性中獲取憑據(jù)信息。
當系統(tǒng)屬性alibabacloud.accessKeyId(密鑰key)、alibabacloud.accessKeyIdSecret(密鑰value)均已設置且不為空時,Credentials工具會優(yōu)先使用它們作為默認憑據(jù)。
您可在運行Java程序時,添加屬性-Dalibabacloud.accessKeyId=*** -Dalibabacloud.accessKeyIdSecret=***
來指定。
2. 使用環(huán)境變量
若不存在優(yōu)先級更高的憑據(jù)信息,Credentials工具會優(yōu)先在環(huán)境變量中獲取憑據(jù)信息。
如果系統(tǒng)環(huán)境變量ALIBABA_CLOUD_ACCESS_KEY_ID(密鑰Key) 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET(密鑰Value) 不為空,Credentials工具會優(yōu)先使用它們作為默認憑據(jù)。
如果系統(tǒng)環(huán)境變量ALIBABA_CLOUD_ACCESS_KEY_ID(密鑰Key)、ALIBABA_CLOUD_ACCESS_KEY_SECRET(密鑰Value)、ALIBABA_CLOUD_SECURITY_TOKEN(Token)均不為空,Credentials工具會優(yōu)先使用STS Token作為默認憑據(jù)。
3. 使用OIDC RAM角色
若不存在優(yōu)先級更高的憑據(jù)信息,Credentials工具會在環(huán)境變量中獲取如下內(nèi)容:
ALIBABA_CLOUD_ROLE_ARN:RAM角色名稱ARN;
ALIBABA_CLOUD_OIDC_PROVIDER_ARN:OIDC提供商ARN;
ALIBABA_CLOUD_OIDC_TOKEN_FILE:OIDC Token文件路徑;
若以上三個環(huán)境變量都已設置內(nèi)容,Credentials將會使用變量內(nèi)容調(diào)用STS服務的AssumeRoleWithOIDC - OIDC角色SSO時獲取扮演角色的臨時身份憑證接口換取STS Token作為默認憑據(jù)。
4. 使用配置文件
若不存在優(yōu)先級更高的憑據(jù)信息,Credentials工具會優(yōu)先在如下位置查找文件是否存在。
Linux系統(tǒng):~/.alibabacloud/credentials.ini
Windows系統(tǒng): C:\Users\USER_NAME\.alibabacloud\credentials.ini
您也可通過環(huán)境變量 ALIBABA_CLOUD_CREDENTIALS_FILE 指定配置文件路徑。如果文件存在,程序?qū)褂门渲梦募?b>default 指定的憑據(jù)信息初始化憑據(jù)客戶端。當然,您也可以通過環(huán)境變量 ALIBABA_CLOUD_PROFILE 來指定憑據(jù)信息,例如設置 ALIBABA_CLOUD_PROFILE 的值為client1。
配置示例信息如下:
[default]
enable=true
type=access_key
access_key_id=<ALIBABA_CLOUD_ACCESS_KEY_ID>
access_key_secret=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
[client1]
enable=true
type=ecs_ram_role
role_name=<ecs_ram_role_name>
[client2]
enable=true
type=ram_role_arn
policy=<policy>
access_key_id=<ALIBABA_CLOUD_ACCESS_KEY_ID>
access_key_secret=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
role_arn=<ram_role_arn>
role_session_name=<role_session_name>
[client3]
enable=true
type=oidc_role_arn
policy=<policy>
oidc_provider_arn=<ALIBABA_CLOUD_ACCESS_KEY_ID>
oidc_token_file_path=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
role_arn=<ram_role_arn>
role_session_name=<role_session_name>
5. 使用ECS實例RAM角色
若不存在優(yōu)先級更高的憑據(jù)信息,Credentials工具會在環(huán)境變量中獲取ALIBABA_CLOUD_ECS_METADATA(ECS實例RAM角色名稱),若存在,程序?qū)ㄟ^ECS的元數(shù)據(jù)服務(Meta Data Server)獲取ECS實例RAM角色的STS Token作為默認憑據(jù)信息。
6. 使用CredentialsURI
若不存在優(yōu)先級更高的憑據(jù)信息,Credentials工具會在環(huán)境變量中獲取ALIBABA_CLOUD_CREDENTIALS_URI,若存在,程序?qū)⒄埱笤揢RI地址,獲取臨時安全憑證作為默認憑據(jù)信息。
如何保護憑據(jù)信息
憑據(jù)信息泄露導致系統(tǒng)被攻擊是云上業(yè)務普遍存在的一種安全問題,您可通過如下方案避免在代碼中暴露明文憑據(jù)信息,降低憑據(jù)泄露的風險。
推薦使用ECS實例RAM角色或者使用STS方式。
推薦使用默認憑據(jù)鏈,使用環(huán)境變量或者配置文件記錄憑據(jù)信息。
如使用顯示初始化方案初始化憑據(jù)客戶端,推薦使用系統(tǒng)屬性及環(huán)境變量記錄憑據(jù)信息,通過
System.getProperty
及System.getenv
獲取。import com.aliyun.credentials.Client; import com.aliyun.credentials.models.Config; public class DemoTest { public static void main(String[] args) throws Exception{ Config credentialConfig = new Config(); credentialConfig.setType("access_key"); credentialConfig.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")); credentialConfig.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")); Client credentialClient = new Client(credentialConfig); } }
如何切換憑據(jù)
當您想要在程序中使用不同的訪問憑據(jù)調(diào)用不同OpenAPI時,可以通過如下方式。
使用多個憑據(jù)客戶端
通過初始化多個憑據(jù)客戶端,傳入到不同的接口請求客戶端。
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
public class DemoTest {
public static void main(String[] args) {
Config credentialConfig1 = new Config();
credentialConfig1.setType("access_key");
credentialConfig1.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
credentialConfig1.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
Client credentialClient1 = new Client(credentialConfig1);
Config credentialConfig2 = new Config();
credentialConfig2.setType("sts");
credentialConfig2.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
credentialConfig2.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
credentialConfig2.setSecurityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN"));
Client credentialClient2 = new Client(credentialConfig2);
}
}
使用AuthUtils
當我們初始化憑據(jù)客戶端采用配置文件記錄憑據(jù)信息時,可以使用AuthUtils.setClientType
切換到不同的憑據(jù)配置上。示例代碼如下。
import com.aliyun.credentials.utils.AuthUtils;
public class Sample {
public static void main(String[] args) {
// 若不配置AuthUtils類clientType屬性,則默認使用default。
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client();
// 切換到client1憑據(jù)上
AuthUtils.setClientType("client1");
com.aliyun.credentials.Client credentialClient1 = new com.aliyun.credentials.Client();
// 切換到client2憑據(jù)上
AuthUtils.setClientType("client2");
com.aliyun.credentials.Client credentialClient2 = new com.aliyun.credentials.Client();
}
}
接口調(diào)用方法
本示例以調(diào)用云服務器ECS的DescribeRegions接口為例,因此需先安裝ECS SDK。
import com.aliyun.credentials.utils.AuthUtils;
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;
public class Sample {
public static void main(String[] args) throws Exception {
// 使用默認憑證初始化Credentials Client。
com.aliyun.credentials.Client defaultCredentialClient = new com.aliyun.credentials.Client();
// 使用配置文件中client1初始化Credentials Client。
AuthUtils.setClientType("client1");
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client();
Config ecsConfig = new Config();
ecsConfig.setEndpoint("ecs.aliyuncs.com");
// 使用默認憑證配置憑證。
ecsConfig.setCredential(defaultCredentialClient);
// 初始化ECS Client。
Client ecsClient = new Client(ecsConfig);
// 初始化DescribeRegions請求。
DescribeRegionsRequest describeRegionsRequest = new DescribeRegionsRequest();
// 初始化運行時配置。
RuntimeOptions runtime = new RuntimeOptions();
// 調(diào)用DescribeRegions接口并獲得響應。
DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeRegionsRequest, runtime);
System.out.println(response.body.toMap());
}
}