您在使用阿里云產品的SDK時,如果引入匹配此SDK的托管憑據插件,則可以通過托管RAM憑據的名稱使用RAM用戶的AccessKey,而無需關心AccessKey是什么,或者它是否被輪換。
工作原理
應用程序使用托管憑據插件后,只需要引用托管RAM憑據(RAM用戶的AccessKey)的憑據名稱。插件將根據憑據名稱從憑據管家獲取憑據的值(AccessKey)并緩存在應用程序的內存中。插件也會以指定的間隔(可配置)從憑據管家重新獲取憑據的值并刷新本地的緩存。
應用程序使用阿里云SDK時,將通過插件緩存的AccessKey對云產品發起請求。
在某些情況下,緩存的RAM憑據不再有效,這通常發生在管理員在憑據管家中人工輪轉憑據,以響應安全事件時。使用無效RAM憑據調用阿里云服務通常會導致應用程序產生異常。如果異常中包含的錯誤代碼為InvalidAccessKeyId.NotFound
或InvalidAccessKeyId
,則托管憑據插件將立即刷新緩存的RAM憑據并重試失敗的請求。
如果使用過期AccessKey調用某些云服務API返回的錯誤代碼和上述所列錯誤碼不同,應用開發人員可以修改默認的錯誤重試行為。更多信息,請參見示例二:修改默認過期處理程序。
支持插件的阿里云SDK
阿里云提供了多種不同的SDK,針對不同SDK的托管憑據插件需要分別開發。下表列出了可以使用托管憑據插件的阿里云SDK。
阿里云SDK名稱 | 支持插件的SDK版本 | 對應SDK的托管憑據插件 |
阿里云Java SDK | 4.3.2~4.5.17 | 阿里云Java SDK托管憑據插件 |
OSS Java SDK | 2.1.0~3.10.2 | OSS Java SDK托管憑據插件 |
消息隊列商業版TCP協議Java SDK | 1.8.5.Final~1.8.7.4.Final | 消息隊列商業版TCP協議Java SDK托管憑據插件 |
如您有其他云產品SDK托管憑據插件需求,可以通過智能在線聯系技術支持人員。
安裝托管憑據插件
針對阿里云的各類Java SDK的托管憑據插件,您可以訪問多種阿里云SDK的托管憑據插件開源代碼倉庫了解更多安裝信息。更多信息,請參見多種阿里云SDK的托管憑據插件開源代碼倉庫。
您可以通過Maven的方式在項目中按需引入阿里云SDK托管憑據Java插件。以下以OSS插件導入為例,為您介紹需要添加的依賴信息。
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-sdk-oss-managed-credentials-provider</artifactId>
<version>x.x.x</version>
</dependency>
示例一:在阿里云SDK中使用托管RAM憑據
- 為云服務的SDK配置托管憑據插件。
您可以通過配置文件(managed_credentials_providers.properties)指定從憑據管家獲取托管憑據的方式,以配置應用接入點的Client Key為例進行介紹。關于如何創建Client Key,請參見為AAP綁定Client Key。
## 配置訪問方式。 credentials_type=client_key ## 讀取Client Key的解密密碼:支持從環境變量或者文件讀取。 client_key_password_from_env_variable=#your client key private key password environment variable name# client_key_password_from_file_path=#your client key private key password file path# ## 讀取Client Key的私鑰文件。 client_key_private_key_path=#your client key private key file path# ## 配置關聯的KMS地域。 cache_client_region_id=[{"regionId":"#regionId#"}]
- 使用托管RAM憑據訪問云服務。
- 方法一:編碼方式(以托管RAM憑據訪問OSS為例)
import com.aliyun.kms.secretsmanager.plugin.oss.ProxyOSSClientBuilder; import com.aliyun.oss.OSS; import com.aliyun.oss.model.Bucket; import java.util.List; public class OssPluginSample { public static void main(String[] args) throws Exception { String secretName = "******"; String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 獲取OSS客戶端。 OSS ossClient = new ProxyOSSClientBuilder().build(endpoint, secretName); List<Bucket> buckets = ossClient.listBuckets(); for (Bucket bucket : buckets) { if (bucket != null) { // do something with bucket } } // 通過以下方法關閉客戶端來釋放插件關聯的資源。 ossClient.shutdown(); } }
- 方法二:Spring Bean方式(以快速集成OSS SDK為例)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean name="proxyOSSClientBuilder" class="com.aliyun.kms.secretsmanager.plugin.oss.ProxyOSSClientBuilder" scope="singleton" /> </beans>
- 方法一:編碼方式(以托管RAM憑據訪問OSS為例)
示例二:修改默認過期處理程序
托管憑據插件默認實現AKExpireHandler的接口調用,用來判斷對云服務的調用是否使用了無效的憑據。使用無效憑據時,插件將重新從憑據管家獲取最新的憑據,然后重試SDK對云服務的調用過程。
AKExpireHandler的接口定義如下:
package com.aliyun.kms.secretsmanager.plugin.common;
public interface AKExpireHandler<TException> {
/**
* 判斷異常是否由AccessKey過期引起。
*
* @param e
* @return
*/
boolean judgeAKExpire(TException e);
}
您可以重新實現AKExpireHandler的接口調用,判斷云服務返回的錯誤碼是否由使用無效AccessKey引起,示例如下:
import com.aliyun.kms.secretsmanager.plugin.sdkcore.ProxyAcsClient;
import com.aliyun.kms.secretsmanager.plugin.common.AKExpireHandler;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import java.util.HashSet;
import java.util.Set;
public class SdkRetrySample {
public static void main(String[]args) throws Exception{
String region="cn-hangzhou";
String secretName="******";
// 獲取阿里云SDK客戶端,并對特定的錯誤碼進行重新獲取憑據。
IAcsClient client = new ProxyAcsClient(
region, secretName, new CustomHandler());
// 業務代碼。
invoke(client,region);
// 通過以下方法關閉客戶端來釋放插件關聯的資源。
client.shutdown();
}
}
class CustomHandler implements AKExpireHandler<ClientException> {
private Set<String> errorCodeSet;
public CustomerHandler() {
errorCodeSet = new HashSet<String>();
// 自行添加錯誤碼,觸發客戶端重新從憑據管家獲取托管的RAM憑據。
errorCodeSet.add("InvalidAccessKeyId.NotFound");
errorCodeSet.add("InvalidAccessKeyId");
}
@Override
public boolean judgeAKExpire(ClientException e) {
return errorCodeSet.contains(e.getErrCode());
}
}