全部產品
Search
文件中心

Alibaba Cloud SDK:管理訪問憑據

更新時間:Jul 01, 2024

當您通過阿里雲SDK調用OpenAPI進行資源操作時,必須正確配置憑證資訊。阿里雲的Credentials工具提供了一套強大的功能,使您能夠輕鬆地擷取和管理這些訪問憑證。無論是利用預設憑證,AccessKey(AK),還是Security Token Service(STS)令牌等,Credentials工具都能為您提供相應支援。此外,本文檔將詳細闡述如何根據優先順序使用預設憑證。您將深入理解如何在阿里雲SDK中配置和維護憑證,從而確保您對雲資源的操作既有效率又具有高度安全性。

背景資訊

憑據是指使用者證明其身份的一組資訊。使用者在系統中進行登入時,需要提供正確的憑據才能驗證身份。常見的憑據類型有:

  1. 阿里雲主帳號和RAM使用者的永久憑據 AccessKey(簡稱AK)。一組由AccessKey ID和AccessKey Secret組成的金鑰組。

  2. 阿里雲RAM角色的STS臨時訪問Token,簡稱STS Token。它是可以自訂時效和存取權限的臨時身份憑據,詳情請參見臨時訪問憑證STS概念

  3. Bearer Token。它是一種身分識別驗證和授權的令牌類型。

前提條件

  • 初次使用阿里雲SDK的開發人員使用者,請優先閱讀快速開始

  • 使用Credentials工具最低要求Java 8(JDK 1.8)。

  • 使用V2.0版本的阿里雲SDK。

  • 自建網關類產品的自研SDK無法使用。

安裝Credentials工具

Maven安裝方式。

<dependency>
   <groupId>com.aliyun</groupId>
   <artifactId>credentials-java</artifactId>
   <version>LATEST</version>
</dependency>
  1. 建議使用最新發行的Credentials版本。

  2. 請查看ChangeLog.txt擷取所有發行的版本列表。

  3. 推薦使用阿里雲V2.0 SDK,若不使用阿里雲V2.0 SDK單獨依賴credentials-java務必引入下面的依賴,否則將報錯找不到com.aliyun.tea.TeaModel類檔案。

    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>tea</artifactId>
      <version>LATEST</version>
    </dependency>

初始化憑據用戶端

Credentials工具支援多種方式初始化憑據用戶端,您可根據實際情況選擇合適的方式進行憑據用戶端初始化。

方式一:使用預設憑據鏈

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

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();
        Client credentialClient = new Client(credentialConfig);
    }
}

介面調用方法

通過預設憑據提供鏈自動建立訪問憑證,並在不使用寫入程式碼AccessKey的情況下成功調用雲產品OpenAPI介面。

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

public class Sample {
    public static void main(String[] args) throws Exception {
        // 使用預設憑證初始化Credentials Client。
        com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client();
        
      	com.aliyun.teaopenapi.models.Config ecsConfig = new com.aliyun.teaopenapi.models.Config();
        // 配置雲產品服務接入地址(endpoint)。
        ecsConfig.setEndpoint("ecs.aliyuncs.com");
        // 使用Credentials配置憑證。
        ecsConfig.setCredential(credentialClient);
        // 初始化ECS Client。
        com.aliyun.ecs20140526.Client ecsClient = new com.aliyun.ecs20140526.Client(ecsConfig);
        // 初始化DescribeRegions請求。
        com.aliyun.ecs20140526.models.DescribeRegionsRequest describeInstancesRequest = new com.aliyun.ecs20140526.models.DescribeRegionsRequest();
        // 初始化運行時配置。
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        // 調用DescribeRegions介面並獲得響應。
        com.aliyun.ecs20140526.models.DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, runtime);
        System.out.println(response.body.toMap());
    }
}

方式二:使用AK

阿里雲帳號、RAM使用者可產生調用OpenAPI的金鑰組AK。如何擷取AK請參見文檔建立AccessKey。您可使用AK初始化憑據用戶端。

警告

阿里雲主帳號擁有資源的全部許可權,AK一旦泄露,會給系統帶來巨大風險,不建議使用。

推薦使用最小化授權的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);
    }
}

介面調用方法

通過Credentials工具讀取AK,完成雲產品OpenAPI介面的調用。

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

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);
        
      	com.aliyun.teaopenapi.models.Config ecsConfig = new com.aliyun.teaopenapi.models.Config();
        // 配置雲產品服務接入地址(endpoint)。
        ecsConfig.setEndpoint("ecs.aliyuncs.com");
        // 使用Credentials配置憑證。
        ecsConfig.setCredential(credentialClient);
        // 初始化ECS Client。
        com.aliyun.ecs20140526.Client ecsClient = new com.aliyun.ecs20140526.Client(ecsConfig);
        // 初始化DescribeRegions請求。
        com.aliyun.ecs20140526.models.DescribeRegionsRequest describeInstancesRequest = new com.aliyun.ecs20140526.models.DescribeRegionsRequest();
        // 初始化運行時配置。
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        // 調用DescribeRegions介面並獲得響應。
        com.aliyun.ecs20140526.models.DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, runtime);
        System.out.println(response.body.toMap());
    }
}

方式三:使用STS Token

以一個RAM使用者的身份調用STS服務的AssumeRole介面,設定Token的最大到期時間,即可換取到臨時憑據STS Token。以下樣本示範如何使用STS Token初始化憑據用戶端(不包含如何擷取到STS Token的過程)。

{
  "RequestId": "EA7A3526-F7DB-54A5-8300-9B742CFAA5EA",
  "AssumedRoleUser": {
    "Arn": "acs:ram::125499367423****:role/STStokenTestRole/STSsessionName",
    "AssumedRoleId": "35219123109646****:STSsessionName"
  },
  "Credentials": {
    "SecurityToken": "exampleToken",
    "AccessKeyId": "STS.exampleAccessKeyID",
    "AccessKeySecret": "exampleAccessKeySecret",
    "Expiration": "2023-03-26T05:26:06Z"
  }
}
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("sts");
      	// <ALIBABA_CLOUD_ACCESS_KEY_ID>需替換為返回資料中擷取的臨時AccessKeyId。
        credentialConfig.setAccessKeyId("<ALIBABA_CLOUD_ACCESS_KEY_ID>");
      	// <ALIBABA_CLOUD_ACCESS_KEY_SECRET>需替換為返回資料中擷取的臨時AccessKeySecret。
        credentialConfig.setAccessKeySecret("<ALIBABA_CLOUD_ACCESS_KEY_SECRET>");
      	// <ALIBABA_CLOUD_SECURITY_TOKEN>需替換為返回資料中擷取的臨時SecurityToken。
        credentialConfig.setSecurityToken("<ALIBABA_CLOUD_SECURITY_TOKEN>");
        Client credentialClient = new Client(credentialConfig);
    }
}

介面調用方法

通過Credentials工具讀取臨時安全性權杖(STS Token),完成雲產品OpenAPI介面的調用。

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝Elastic Compute Service SDKSecurity Token Service SDK

public class Sample {
    public static void main(String[] args) throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填,請確保代碼運行環境設定了環境變數 ALIBABA_CLOUD_ACCESS_KEY_ID。
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                // 必填,請確保代碼運行環境設定了環境變數 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        // Endpoint 請參考 https://api.aliyun.com/product/Sts
        config.endpoint = "sts.cn-hangzhou.aliyuncs.com";
        // 建立StsClient對象
        com.aliyun.sts20150401.Client client = new com.aliyun.sts20150401.Client(config);
        com.aliyun.sts20150401.models.AssumeRoleRequest assumeRoleRequest = new com.aliyun.sts20150401.models.AssumeRoleRequest()
                .setRoleArn("acs:ram::125499367423****:role/STStokenTestRole/STSsessionName")
                .setRoleSessionName("35219123109646****:STSsessionName");
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            com.aliyun.sts20150401.models.AssumeRoleResponse assumeRoleResponse = client.assumeRoleWithOptions(assumeRoleRequest, runtime);
            com.aliyun.sts20150401.models.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);

            // 建立ecs client。
            com.aliyun.teaopenapi.models.Config ecsConfig = new com.aliyun.teaopenapi.models.Config();
            ecsConfig.setEndpoint("ecs.aliyuncs.com");  // 配置雲產品服務接入地址(endpoint)。
            ecsConfig.setCredential(credentialClient);  // 使用Credentials配置憑證。
            com.aliyun.ecs20140526.Client ecsClient = new com.aliyun.ecs20140526.Client(ecsConfig);
            // 初始化DescribeRegions請求。
            com.aliyun.ecs20140526.models.DescribeRegionsRequest describeInstancesRequest = new com.aliyun.ecs20140526.models.DescribeRegionsRequest();
            // 初始化運行時配置。
            com.aliyun.teautil.models.RuntimeOptions describeRegionsRuntime = new com.aliyun.teautil.models.RuntimeOptions();
            // 調用DescribeRegions介面並獲得響應。
            com.aliyun.ecs20140526.models.DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, describeRegionsRuntime);
            System.out.println(response.body.toMap());
        } catch (com.aliyun.tea.TeaException error) {
            // 錯誤 message
            System.out.println(error.getMessage());
            // 診斷地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception ex) {
            // 錯誤 message
            System.out.println(ex.getMessage());
        }
    }
}

方式四:使用AK及RamRoleArn

該方式底層實現是STS Token。通過指定RAM角色的ARN(Alibabacloud Resource Name),Credentials工具可以協助開發人員前往STS換取STS Token。您也可調用setPolicy函數限制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
    credentialConfig.setRoleArn("<RoleArn>");
    // 角色會話名稱
    credentialConfig.setRoleSessionName("<RoleSessionName>");
    // 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
    credentialConfig.setPolicy("<Policy>");
    credentialConfig.setRoleSessionExpiration(3600);
    Client credentialClient = new Client(credentialConfig);
  }
}

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

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");
        // 設定為AccessKey ID值。
        credentialsConfig.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
        // 設定為AccessKey Secret值。
        credentialsConfig.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        // 要扮演的RAM角色ARN,樣本值:acs:ram::123456789012****:role/adminrole
        credentialsConfig.setRoleArn("<RoleArn>");
        // 角色會話名稱
        credentialsConfig.setRoleSessionName("<RoleSessionName>");
        // 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
        credentialsConfig.setPolicy("<Policy>");
        // 會話有效時間
        credentialsConfig.setRoleSessionExpiration(3600);
        com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialsConfig);

        com.aliyun.teaopenapi.models.Config ecsConfig = new com.aliyun.teaopenapi.models.Config();
        // 配置雲產品服務接入地址(endpoint)。
        ecsConfig.setEndpoint("ecs.aliyuncs.com");
        // 使用Credentials配置憑證。
        ecsConfig.setCredential(credentialClient);
        // 初始化ECS Client。
        com.aliyun.ecs20140526.Client ecsClient = new com.aliyun.ecs20140526.Client(ecsConfig);
        // 初始化DescribeRegions請求。
        com.aliyun.ecs20140526.models.DescribeRegionsRequest describeInstancesRequest = new com.aliyun.ecs20140526.models.DescribeRegionsRequest();
        // 初始化運行時配置。
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        // 調用DescribeRegions介面並獲得響應。
        com.aliyun.ecs20140526.models.DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, runtime);
        System.out.println(response.body.toMap());
    }
}

方式五:使用ECS執行個體RAM角色和中繼資料普通模式

該方式底層實現是STS Token。Credentials工具會自動擷取ECS執行個體綁定的RAM角色,調用ECS的中繼資料服務(Meta Data Server)換取STS Token,完成憑據用戶端初始化。ECI執行個體,Container Service for Kubernetes的Worker節點均支援綁定執行個體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角色的角色名稱,不填會自動擷取,但是建議加上以減少請求次數
        credentialConfig.setRoleName("<RoleName>");
        Client credentialClient = new Client(credentialConfig);
    }
}

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

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角色的角色名稱,不填會自動擷取,但是建議加上以減少請求次數
      	credentialsConfig.setRoleName("<RoleName>");
        com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialsConfig);
        
      	com.aliyun.teaopenapi.models.Config ecsConfig = new com.aliyun.teaopenapi.models.Config();
        // 配置雲產品服務接入地址(endpoint)。
        ecsConfig.setEndpoint("ecs.aliyuncs.com");
        // 使用Credentials配置憑證。
        ecsConfig.setCredential(credentialClient);
        // 初始化ECS Client。
        com.aliyun.ecs20140526.Client ecsClient = new com.aliyun.ecs20140526.Client(ecsConfig);
        // 初始化DescribeRegions請求。
        com.aliyun.ecs20140526.models.DescribeRegionsRequest describeInstancesRequest = new com.aliyun.ecs20140526.models.DescribeRegionsRequest();
        // 初始化運行時配置。
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        // 調用DescribeRegions介面並獲得響應。
        com.aliyun.ecs20140526.models.DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, runtime);
        System.out.println(response.body.toMap());
    }
}

方式六:使用ECS執行個體RAM角色和中繼資料加固模式

什麼是加固模式,請參見加固模式的介紹。通過採用ECS執行個體的中繼資料加固策略來擷取RAM角色的初始化憑據。相較於普通模式,此方式採納了一種更為嚴謹的安全邏輯:首先在ECS執行個體內部自動產生一個具有時效限制的token,利用此token作為憑據,向中繼資料服務(Metadata Server)請求獲得STS(Security Token Service)臨時憑證。這一系列操作構成了憑據用戶端的安全初始化流程。

加固模式的核心優勢在於,ECS執行個體內部產生的token不僅具備動態性,還嚴格限制了有效時間,大大降低了外部攻擊者通過預測或偽造token來非法訪問中繼資料服務的可能性,從而有效抵禦了伺服器端請求偽造(SSRF, Server-Side Request Forgery)等多種網路安全隱患。總之,採用ECS執行個體中繼資料加固模式,不僅加強了身分識別驗證的嚴密性,還顯著提高了整體系統的安全性,為雲上資源的訪問與管理增設了一道堅固的防線。

import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;

public class DemoTest {
    public static void main(String[] args) {
        Config credentialConfig = new Config();
        // Which type of credential you want
        credentialConfig.setType("ecs_ram_role");
        // `roleName` is optional. It will be retrieved automatically if not set. It is highly recommended to set it up to reduce requests
        credentialConfig.setRoleName("RoleName");
        // `enableIMDSv2` is optional and is recommended to be turned on. It can be replaced by setting environment variable: ALIBABA_CLOUD_ECS_IMDSV2_ENABLE
        credentialConfig.setEnableIMDSv2(true);
        Client credentialClient = new Client(credentialConfig);
    }
}
重要
  • enable_imds_v2的預設值為false,表示通過ECS執行個體中繼資料普通模式擷取RAM角色初始化憑據用戶端。

  • 通過ECS執行個體中繼資料加固模式擷取RAM角色初始化憑據用戶端時,enable_imds_v2的值為true

介面調用方法

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角色的角色名稱,不填會自動擷取,但是建議加上以減少請求次數
        credentialsConfig.setRoleName("<RoleName>");
        // 選填,是否開啟ECS IMDSv2
        credentialsConfig.setEnableIMDSv2(true);
        com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialsConfig);

        com.aliyun.teaopenapi.models.Config ecsConfig = new com.aliyun.teaopenapi.models.Config();
        // 配置雲產品服務接入地址(endpoint)。
        ecsConfig.setEndpoint("ecs.aliyuncs.com");
        // 使用Credentials配置憑證。
        ecsConfig.setCredential(credentialClient);
        // 初始化ECS Client。
        com.aliyun.ecs20140526.Client ecsClient = new com.aliyun.ecs20140526.Client(ecsConfig);
        // 初始化DescribeRegions請求。
        com.aliyun.ecs20140526.models.DescribeRegionsRequest describeInstancesRequest = new com.aliyun.ecs20140526.models.DescribeRegionsRequest();
        // 初始化運行時配置。
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        // 調用DescribeRegions介面並獲得響應。
        com.aliyun.ecs20140526.models.DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, runtime);
        System.out.println(response.body.toMap());
    }
}

方式七:使用OIDCRoleArn

Container Service for Kubernetes中設定了Worker節點RAM角色後,對應節點內的Pod中的應用也就可以像ECS上部署的應用一樣,通過中繼資料服務(Meta Data Server)擷取關聯角色的STS Token。但如果容器叢集上部署的是不可信的應用(比如部署您的客戶提交的應用,代碼也沒有對您開放),您可能並不希望它們能通過中繼資料服務擷取Worker節點關聯執行個體RAM角色的STS Token。為了避免影響雲上資源的安全,同時又能讓這些不可信的應用安全地擷取所需的 STS Token,實現應用層級的許可權最小化,您可以使用RRSA(RAM Roles for Service Account)功能。阿里雲容器叢集會為不同的應用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檔案路徑;

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");
    credentialConfig.setRoleArn(System.getenv("ALIBABA_CLOUD_ROLE_ARN"));
    credentialConfig.setOidcProviderArn(System.getenv("ALIBABA_CLOUD_OIDC_PROVIDER_ARN"));
    credentialConfig.setOidcTokenFilePath(System.getenv("ALIBABA_CLOUD_OIDC_TOKEN_FILE"));
    // 角色會話名稱
    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>");
    // 設定session到期時間
    credentialConfig.setRoleSessionExpiration(3600);
    Client credentialClient = new Client(credentialConfig);
  }
}

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

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");
        credentialsConfig.setRoleArn(System.getenv("ALIBABA_CLOUD_ROLE_ARN"));
    		credentialsConfig.setOidcProviderArn(System.getenv("ALIBABA_CLOUD_OIDC_PROVIDER_ARN"));
    		credentialsConfig.setOidcTokenFilePath(System.getenv("ALIBABA_CLOUD_OIDC_TOKEN_FILE"));
    		// 角色會話名稱
    		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>");
    		// 設定session到期時間
    		credentialsConfig.setRoleSessionExpiration(3600);
        com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialsConfig);
        
      	com.aliyun.teaopenapi.models.Config ecsConfig = new com.aliyun.teaopenapi.models.Config();
        // 配置雲產品服務接入地址(endpoint)。
        ecsConfig.setEndpoint("ecs.aliyuncs.com");
        // 使用Credentials配置憑證。
        ecsConfig.setCredential(credentialClient);
        // 初始化ECS Client。
        com.aliyun.ecs20140526.Client ecsClient = new com.aliyun.ecs20140526.Client(ecsConfig);
        // 初始化DescribeRegions請求。
        com.aliyun.ecs20140526.models.DescribeRegionsRequest describeInstancesRequest = new com.aliyun.ecs20140526.models.DescribeRegionsRequest();
        // 初始化運行時配置。
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        // 調用DescribeRegions介面並獲得響應。
        com.aliyun.ecs20140526.models.DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, runtime);
        System.out.println(response.body.toMap());
    }
}

方式八:使用URI憑據

該方案底層實現是STS Token。Credentials工具通過您提供的URI擷取STS 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("credentials_uri");
        // 換取憑證的 URI,格式為http://local_or_remote_uri/
        credentialConfig.setCredentialsUri("<local_or_remote_uri>");
        Client credentialClient = new Client(credentialConfig);
    }
}

介面調用方法

指定Credentials提供地址,實現通過本地或遠端URI來擷取並自動更新Token,完成雲產品介面的調用。

調用單個雲產品的介面需要雲產品依賴。本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

public class Sample {
    public static void main(String[] args) throws Exception {
        // 使用URI憑據初始化Credentials Client。
        com.aliyun.credentials.models.Config credentialsConfig = new com.aliyun.credentials.models.Config();
        // 憑證類型。
      	credentialsConfig.setType("credentials_uri");
        // Credentials URI,格式為http://local_or_remote_uri/。
      	credentialsConfig.setCredentialsUri("<local_or_remote_uri>");
        com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialsConfig);
        
      	com.aliyun.teaopenapi.models.Config ecsConfig = new com.aliyun.teaopenapi.models.Config();
        // 配置雲產品服務接入地址(endpoint)。
        ecsConfig.setEndpoint("ecs.aliyuncs.com");
        // 使用Credentials配置憑證。
        ecsConfig.setCredential(credentialClient);
        // 初始化ECS Client。
        com.aliyun.ecs20140526.Client ecsClient = new com.aliyun.ecs20140526.Client(ecsConfig);
        // 初始化DescribeRegions請求。
        com.aliyun.ecs20140526.models.DescribeRegionsRequest describeInstancesRequest = new com.aliyun.ecs20140526.models.DescribeRegionsRequest();
        // 初始化運行時配置。
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        // 調用DescribeRegions介面並獲得響應。
        com.aliyun.ecs20140526.models.DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, runtime);
        System.out.println(response.body.toMap());
    }

方式九:使用Bearer Token

目前只有Cloud Call CenterCCC這款產品支援Bearer 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("bearer");
        // 填入您的Bearer Token
        credentialConfig.setBearerToken("<BearerToken>");
        Client credentialClient = new Client(credentialConfig);
    }
}

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

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.setCredentialsUri("<bearer_token>");
        com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialsConfig);
        
        com.aliyun.teaopenapi.models.Config ecsConfig = new com.aliyun.teaopenapi.models.Config();
        // 配置雲產品服務接入地址(endpoint)。
      	ecsConfig.setEndpoint("ecs.aliyuncs.com");
      	// 使用Credentials配置憑證。
        ecsConfig.setCredential(credentialClient);
      	// 初始化ECS Client。
        com.aliyun.ecs20140526.Client ecsClient = new com.aliyun.ecs20140526.Client(ecsConfig);
        // 初始化DescribeRegions請求。
        com.aliyun.ecs20140526.models.DescribeRegionsRequest describeInstancesRequest = new com.aliyun.ecs20140526.models.DescribeRegionsRequest();
        // 初始化運行時配置。
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        // 調用DescribeRegions介面並獲得響應。
        com.aliyun.ecs20140526.models.DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeInstancesRequest, runtime);
        System.out.println(response.body.toMap());
    }
}

預設憑據鏈

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

1. 使用系統屬性

Credentials工具會優先在系統屬性中擷取憑據資訊。

當系統屬性alibabacloud.accessKeyId密鑰key)、alibabacloud.accessKeyIdSecret(密鑰value均已設定且不為空白時,Credentials工具會優先使用它們作為預設憑據。

您可在運行Java程式時,添加屬性-Dalibabacloud.accessKeyId=*** -Dalibabacloud.accessKeyIdSecret=***來指定。

2. 使用環境變數

若不存在優先順序更高的憑據資訊,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作為預設憑據。

3. 使用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作為預設憑據。

4. 使用設定檔

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

Linux系統:~/.alibabacloud/credentials

Windows系統: C:\Users\USER_NAME\.alibabacloud\credentials

您也可通過指定 ALIBABA_CLOUD_CREDENTIALS_FILE 指定設定檔路徑。如果檔案存在,程式將會使用設定檔中default 指定的憑據資訊初始化憑據用戶端,當然您也可以通過設定 ALIBABA_CLOUD_PROFILE 環境變數修改預設讀取的憑據資訊。

配置樣本資訊如下:

[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=sts
access_key_id=<ALIBABA_CLOUD_ACCESS_KEY_ID>
access_key_secret=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
security_token=<security_token>

[client2]
enable=true
type=ecs_ram_role
role_name=<ecs_ram_role_name>

[client3]
enable=true
type=ram_role_arn
policy=<policy_name>
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>

5. 使用ECS執行個體RAM角色

若不存在優先順序更高的憑據資訊,Credentials工具會在環境變數中擷取ALIBABA_CLOUD_ECS_METADATA(ECS執行個體RAM角色名稱),若存在,程式將會通過ECS的中繼資料服務(Meta Data Server)擷取ECS執行個體RAM角色的STS Token作為預設憑據資訊。

如何保護憑據資訊

憑據資訊泄露導致系統被攻擊是雲上業務普遍存在的一種安全問題,您可通過如下方案避免在代碼中暴露明文憑據資訊,降低憑據泄露的風險。

  1. 推薦使用ECS執行個體RAM角色或者使用STS方式。

  2. 推薦使用預設憑據鏈,使用環境變數或者設定檔記錄憑據資訊。

  3. 如使用顯示初始化方案初始化憑據用戶端,推薦使用系統屬性及環境變數記錄憑據資訊,通過System.getPropertySystem.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);
        }
    }

如何切換憑據

當您想要在程式中使用不同的訪問憑據調用不同OpenAPI時,可以通過如下方式。

使用多個憑據用戶端

通過初始化多個憑據用戶端,傳入到不同的介面請求用戶端。

import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;

public class DemoTest {
    public static void main(String[] args) throws Exception{
        Config credentialConfig1 = new Config();
        credentialConfig1.setType("access_key");
        credentialConfig1.setAccessKeyId("<ALIBABA_CLOUD_ACCESS_KEY_ID>");
        credentialConfig1.setAccessKeySecret("<ALIBABA_CLOUD_ACCESS_KEY_SECRET>");
        Client credentialClient1 = new Client(credentialConfig1);
      
        Config credentialConfig2 = new Config();
        credentialConfig2.setType("access_key");
        credentialConfig2.setAccessKeyId("<ALIBABA_CLOUD_ACCESS_KEY_ID>");
        credentialConfig2.setAccessKeySecret("<ALIBABA_CLOUD_ACCESS_KEY_SECRET>");
        Client credentialClient2 = new Client(credentialConfig2);
    }
}

使用AuthUtils

當我們初始化憑據用戶端採用設定檔記錄憑據資訊時,可以使用AuthUtils.setClientType切換到不同的憑據配置上。

[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=sts
access_key_id=<ALIBABA_CLOUD_ACCESS_KEY_ID>
access_key_secret=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
security_token=<security_token>

[client2]
enable=true
type=ecs_ram_role
role_name=<ecs_ram_role_name>

範例程式碼如下。

import com.aliyun.credentials.utils.AuthUtils;
// 若不配置AuthUtils類clientType屬性,則預設使用default。
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client();
// 切換到client1憑據上
AuthUtils.setClientType("client1");
com.aliyun.credentials.Client credentialClient1 = new com.aliyun.credentials.Client();
// 切換到client2憑據上
AuthUtils.setClientType("client2");
com.aliyun.credentials.Client credentialClient2 = new com.aliyun.credentials.Client();

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝。

public class Sample {
    public static void main(String[] args) throws Exception {
        // 使用預設憑證初始化Credentials Client。
        com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client();
        /* 使用設定檔中client1初始化Credentials Client。*/
        com.aliyun.credentials.utils.AuthUtils.setClientType("client1");
        com.aliyun.credentials.Client credentialClient1 = new com.aliyun.credentials.Client();

        com.aliyun.teaopenapi.models.Config ecsConfig = new com.aliyun.teaopenapi.models.Config();
        // 配置雲產品服務接入地址(endpoint)。
        ecsConfig.setEndpoint("ecs.aliyuncs.com");
        // 使用Credentials配置憑證。
        ecsConfig.setCredential(credentialClient);
        // 初始化ECS Client。
        com.aliyun.ecs20140526.Client ecsClient = new com.aliyun.ecs20140526.Client(ecsConfig);
        // 初始化DescribeRegions請求。
        com.aliyun.ecs20140526.models.DescribeRegionsRequest describeRegionsRequest = new com.aliyun.ecs20140526.models.DescribeRegionsRequest();
        // 初始化運行時配置。
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        // 調用DescribeRegions介面並獲得響應。
        com.aliyun.ecs20140526.models.DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(describeRegionsRequest, runtime);
        System.out.println(response.body.toMap());
    }
}

相關文檔