全部產品
Search
文件中心

Object Storage Service:如何為OSS Java SDK配置訪問憑證

更新時間:Apr 02, 2025

使用Java SDK發起OSS請求,您需要配置訪問憑證。阿里雲服務會通過訪問憑證驗證您的身份資訊和存取權限。您可以根據使用情境對認證和授權的要求,選擇不同的方式提供憑證。

注意事項

  • 如果您希望擷取關於OSS支援的Region與Endpoint的對應關係,請參見OSS地區和訪問網域名稱

  • 如果您希望建立RAM使用者的AccessKey,請參見建立AccessKey

  • 請您使用OSS Java SDK 3.17.4及以上版本以支援V4簽名,詳情請參見安裝SDK

憑證提供者選型參考

OSS支援多種方式初始化憑證提供者,您可以根據使用情境對認證和授權的要求,選擇對應的方式初始化憑證提供者。

憑證提供者初始化方式

適用情境

是否需要提供前置的AK或STS Token

底層實現基於的憑證

憑證有效期間

憑證輪轉或重新整理方式

使用RAM使用者的AK

部署運行在安全、穩定且不易受外部攻擊的環境的應用程式,無需頻繁輪轉憑證就可以長期訪問雲端服務

AK

長期

手動輪轉

使用STS臨時訪問憑證

部署運行在不可信的環境的應用程式,希望能控制訪問的有效期間、許可權

STS Token

臨時

手動重新整理

使用RAMRoleARN

需要授權訪問雲端服務,例如跨阿里雲帳號訪問雲端服務的應用程式

STS Token

臨時

自動重新整理

使用ECSRAMRole

部署運行在阿里雲的ECS執行個體、ECI執行個體、Container ServiceKubernetes版的Worker節點中的應用程式

STS Token

臨時

自動重新整理

使用OIDCRoleARN

部署運行在阿里雲的Container ServiceKubernetes版的Worker節點中的不可信應用程式

STS Token

臨時

自動重新整理

使用Function Compute上下文中的Credentials

部署運行在阿里雲Function Compute中的應用程式的函數

STS Token

臨時

無需重新整理

使用CredentialsURI

需要通過外部系統擷取訪問憑證的應用程式

STS Token

臨時

自動重新整理

使用自動輪轉的AK

部署運行在面臨AK泄露風險的環境的應用程式,需要頻繁輪轉憑證才長期能訪問雲端服務

AK

長期

自動輪轉

使用自訂訪問憑證

如果以上憑證配置方式都不滿足要求時,您可以自訂擷取憑證的方式

自訂

自訂

自訂

自訂

使用預設憑據鏈

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

自訂

自訂

自動重新整理

常用配置樣本

使用RAM使用者的AK

如果您的應用程式部署運行在安全、穩定且不易受外部攻擊的環境中,需要長期訪問您的OSS,且不能頻繁輪轉憑證時,您可以使用阿里雲主帳號或RAM使用者的AK(Access Key ID、Access Key Secret)初始化憑證提供者。需要注意的是,該方式需要您手動維護一個AK,存在安全性風險和維護複雜度增加的風險。

警告
  • 阿里雲帳號擁有資源的全部許可權,AK一旦泄露,會給系統帶來巨大風險,不建議使用。推薦使用最小化授權的RAM使用者的AK。

  • 如需建立RAM使用者的AK,請直接存取建立AccessKey。RAM使用者的Access Key ID、Access Key Secret資訊僅在建立時顯示,請及時儲存,如若遺忘請考慮建立新的AK進行輪換。

環境變數

  1. 使用RAM使用者AccessKey配置環境變數。

    Linux
    1. 在命令列介面執行以下命令來將環境變數設定追加到~/.bashrc 檔案中。

      echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bashrc
      echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bashrc
      1. 執行以下命令使變更生效。

        source ~/.bashrc
      2. 執行以下命令檢查環境變數是否生效。

        echo $OSS_ACCESS_KEY_ID
        echo $OSS_ACCESS_KEY_SECRET
    macOS
    1. 在終端中執行以下命令,查看預設Shell類型。

      echo $SHELL
      1. 根據預設Shell類型進行操作。

        Zsh
        1. 執行以下命令來將環境變數設定追加到 ~/.zshrc 檔案中。

          echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.zshrc
          echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.zshrc
        2. 執行以下命令使變更生效。

          source ~/.zshrc
        3. 執行以下命令檢查環境變數是否生效。

          echo $OSS_ACCESS_KEY_ID
          echo $OSS_ACCESS_KEY_SECRET
        Bash
        1. 執行以下命令來將環境變數設定追加到 ~/.bash_profile 檔案中。

          echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bash_profile
          echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bash_profile
        2. 執行以下命令使變更生效。

          source ~/.bash_profile
        3. 執行以下命令檢查環境變數是否生效。

          echo $OSS_ACCESS_KEY_ID
          echo $OSS_ACCESS_KEY_SECRET
    Windows
    CMD
    1. 在CMD中運行以下命令。

      setx OSS_ACCESS_KEY_ID "YOUR_ACCESS_KEY_ID"
      setx OSS_ACCESS_KEY_SECRET "YOUR_ACCESS_KEY_SECRET"
      1. 運行以下命令,檢查環境變數是否生效。

        echo %OSS_ACCESS_KEY_ID%
        echo %OSS_ACCESS_KEY_SECRET%
    PowerShell
    1. 在PowerShell中運行以下命令。

      [Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User)
      [Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", "YOUR_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)
      1. 運行以下命令,檢查環境變數是否生效。

        [Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User)
        [Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)
  2. 參考上述方式修改系統內容變數後,請重啟或重新整理您的編譯運行環境,包括IDE、命令列介面、其他傳統型應用程式及後台服務,以確保最新的系統內容變數成功載入。

  3. 使用環境變數來傳遞憑證資訊。

    import com.aliyun.oss.common.auth.CredentialsProviderFactory;
    import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
    
    public class AkDemoTest {
        public static void main(String[] args) throws Exception {
            // 從環境變數中擷取憑證
            EnvironmentVariableCredentialsProvider credentialsProvider =  CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
            // 使用credentialsProvider進行後續操作...
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);   
            // 建立OSSClient執行個體。
            OSS ossClient = OSSClientBuilder.create()
                    .endpoint("endpoint")
                    .credentialsProvider(credentialsProvider)
                    .clientConfiguration(clientBuilderConfiguration)
                    .region("region")
                    .build();
                    
            ossClient.shutdown();
        }
    }

靜態憑證

以下範例程式碼展示了如何對訪問憑據直接進行寫入程式碼,顯式設定要使用的存取金鑰。

警告

請勿將訪問憑據嵌入到生產環境的應用程式中,此方法僅用於測試目的。

import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import java.io.FileInputStream;

public class AkDemoTest {
    public static void main(String[] args) throws Exception {
        // 填寫RAM使用者的Access Key ID和Access Key Secret
        String accessKeyId = "yourAccessKeyID";
        String accessKeySecret = "yourAccessKeySecret";
        
        // 使用DefaultCredentialProvider方法直接設定AK和SK
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);

        // 使用credentialsProvider初始化用戶端
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        // 顯式聲明使用 V4 簽名演算法
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);  
        // 建立OSSClient執行個體。
        OSS ossClient = OSSClientBuilder.create()
                .endpoint("endpoint")
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region("region")
                .build();

        ossClient.shutdown();

    }
}

使用STS臨時訪問憑證

如果您的應用程式需要臨時訪問OSS,您可以使用通過STS服務擷取的臨時身份憑證(Access Key ID、Access Key Secret和Security Token)初始化憑證提供者。需要注意的是,該方式需要您手動維護一個STS Token,存在安全性風險和維護複雜度增加的風險。此外,如果您需要多次臨時訪問OSS,您需要手動重新整理STS Token。

重要

環境變數

  1. 使用臨時身份憑證設定環境變數。

    Mac OS X/Linux/Unix

    警告
    • 請注意,此處使用的是通過STS服務擷取的臨時身份憑證(Access Key ID、Access Key Secret和Security Token),而非RAM使用者的Access Key和Access Key Secret。

    • 請注意區分STS服務擷取的Access Key ID以STS開頭,例如“STS.****************”。

    export OSS_ACCESS_KEY_ID=<STS_ACCESS_KEY_ID>
    export OSS_ACCESS_KEY_SECRET=<STS_ACCESS_KEY_SECRET>
    export OSS_SESSION_TOKEN=<STS_SECURITY_TOKEN>

    Windows

    警告
    • 請注意,此處使用的是通過STS服務擷取的臨時身份憑證(Access Key ID、Access Key Secret和Security Token),而非RAM使用者的AK(Access Key ID、Access Key Secret)。

    • 請注意區分STS服務擷取的Access Key ID以STS開頭,例如“STS.****************”。

    set OSS_ACCESS_KEY_ID=<STS_ACCESS_KEY_ID>
    set OSS_ACCESS_KEY_SECRET=<STS_ACCESS_KEY_SECRET>
    set OSS_SESSION_TOKEN=<STS_SECURITY_TOKEN>
  2. 通過環境變數來傳遞憑證資訊。

    import com.aliyun.oss.common.auth.CredentialsProviderFactory;
    import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
    
    public class StsDemoTest {
        public static void main(String[] args) throws Exception {
            // 從環境變數中擷取憑證
            EnvironmentVariableCredentialsProvider credentialsProvider =  CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
            
            // 使用credentialsProvider初始化用戶端
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            // 顯式聲明使用 V4 簽名演算法
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);  
            // 建立OSSClient執行個體。
            OSS ossClient = OSSClientBuilder.create()
                    .endpoint("endpoint")
                    .credentialsProvider(credentialsProvider)
                    .clientConfiguration(clientBuilderConfiguration)
                    .region("region")
                    .build();
    
            ossClient.shutdown();
        }
    }

靜態憑證

您可以在應用程式中對憑據直接進行寫入程式碼,顯式設定要使用的臨時存取金鑰。

import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;

public class StsDemoTest {
    public static void main(String[] args) throws Exception {
        // 請設定為您通過STS服務擷取的臨時身份憑證Access Key ID、Access Key Secret和Security Token,而非RAM使用者的身份憑證資訊
        // 請注意區分STS服務擷取的Access Key ID是以STS開頭,如下所示
        String accessKeyId = "STS.****************";
        String accessKeySecret = "yourAccessKeySecret";
        String stsToken= "yourSecurityToken";
        
        // 使用DefaultCredentialProvider方法直接設定AK和SK
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret, stsToken);

        // 使用credentialsProvider初始化用戶端
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        // 顯式聲明使用 V4 簽名演算法
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);  
        // 建立OSSClient執行個體。
        OSS ossClient = OSSClientBuilder.create()
                .endpoint("endpoint")
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region("region")
                .build();

        ossClient.shutdown();
    }
}

更多情境化配置樣本

使用RAMRoleARN

如果您的應用程式需要授權訪問OSS,例如跨阿里雲帳號訪問OSS,您可以使用RAMRoleARN初始化憑證提供者。該方式底層實現是STS Token。通過指定RAM角色的ARN(Alibabacloud Resource Name),Credentials工具會前往STS服務擷取STS Token,並在會話到期前調用AssumeRole介面申請新的STS Token。此外,您還可以通過為policy賦值來限制RAM角色到一個更小的許可權集合。

重要
  • 阿里雲帳號擁有資源的全部許可權,AK一旦泄露,會給系統帶來巨大風險,不建議使用。推薦使用最小化授權的RAM使用者的AK。

  • 如需建立RAM使用者的AK,請直接存取建立AccessKey。RAM使用者的Access Key ID、Access Key Secret資訊僅在建立時顯示,請及時儲存,如若遺忘請考慮建立新的AK進行輪換。

  • 如需擷取RAMRoleARN,請直接存取CreateRole - 建立角色

  1. 添加credentials依賴。

    <!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java -->
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>credentials-java</artifactId>
        <version>LATEST</version>
    </dependency>
  2. 配置AK和RAMRoleARN作為訪問憑證。

    import com.aliyun.credentials.models.CredentialModel;
    import com.aliyun.oss.common.auth.Credentials;
    import com.aliyun.oss.common.auth.CredentialsProvider;
    import com.aliyun.oss.common.auth.DefaultCredentials;
    
    public class RamRoleArnAkDemoTest {
    
        public static void main(String[] args) {
    
            com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config();
            // 訪問憑證類型。固定為ram_role_arn
            config.setType("ram_role_arn");
            // 要扮演的RAM角色ARN,樣本值:acs:ram::123456789012****:role/adminrole,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定RoleArn
            config.setRoleArn("<RoleArn>");
            // 從環境變數中擷取AccessKeyId
            config.setAccessKeyId(System.getenv().get("ALIBABA_CLOUD_ACCESS_KEY_ID"));
            // 從環境變數中擷取AccessKeySecret
            config.setAccessKeySecret(System.getenv().get("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
            // 角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定RoleSessionName
            config.setRoleName("<RoleSessionName>");
            // 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
            config.setPolicy("<Policy>");
            // 設定角色會話有效期間,非必填
            config.setRoleSessionExpiration(3600);
    
            final com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client(config);
    
            CredentialsProvider credentialsProvider = new CredentialsProvider(){
                @Override
                public void setCredentials(Credentials credentials) {
                }
    
                @Override
                public Credentials getCredentials() {
                    CredentialModel credential = credentialsClient.getCredential();
                    return  new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken());
                }
            };
            // 使用credentialsProvider初始化用戶端
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            // 顯式聲明使用 V4 簽名演算法
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);  
            // 建立OSSClient執行個體。
            OSS ossClient = OSSClientBuilder.create()
                    .endpoint("endpoint")
                    .credentialsProvider(credentialsProvider)
                    .clientConfiguration(clientBuilderConfiguration)
                    .region("region")
                    .build();
    
            ossClient.shutdown();
        }
    }

使用ECSRAMRole

如果您的應用程式運行在ECS執行個體、ECI執行個體、Container ServiceKubernetes版的Worker節點中,建議您使用ECSRAMRole初始化憑證提供者。該方式底層實現是STS Token。ECSRAMRole允許您將一個角色關聯到ECS執行個體、ECI執行個體或Container Service Kubernetes 版的Worker節點,實現在執行個體內部自動重新整理STS Token。該方式無需您提供一個AK或STS Token,消除了手動維護AK或STS Token的風險。如何擷取ECSRAMRole,請參見CreateRole - 建立角色。如何將一個角色關聯到ECS執行個體,請參見執行個體RAM角色

  1. 添加credentials依賴。

    <!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java -->
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>credentials-java</artifactId>
        <version>LATEST</version>
    </dependency>
  2. 配置ECSRAMRole作為訪問憑證。

    import com.aliyun.credentials.models.CredentialModel;
    import com.aliyun.oss.common.auth.Credentials;
    import com.aliyun.oss.common.auth.CredentialsProvider;
    import com.aliyun.oss.common.auth.DefaultCredentials;
    
    public class EcsRamRoleDemoTest {
        public static void main(String[] args) {
    
            com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config();
            // 訪問憑證類型。固定為ecs_ram_role。
            config.setType("ecs_ram_role");
            // 為ECS執行個體分配的RAM角色名稱。
            config.setRoleName("<RoleName>");
    
            final com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client(config);
    
            CredentialsProvider credentialsProvider = new CredentialsProvider(){
                @Override
                public void setCredentials(Credentials credentials) {
                }
    
                @Override
                public Credentials getCredentials() {
                    CredentialModel credential = credentialsClient.getCredential();
                    return  new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken());
                }
            };
            // 使用credentialsProvider初始化用戶端
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            // 顯式聲明使用 V4 簽名演算法
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);  
            // 建立OSSClient執行個體。
            OSS ossClient = OSSClientBuilder.create()
                    .endpoint("endpoint")
                    .credentialsProvider(credentialsProvider)
                    .clientConfiguration(clientBuilderConfiguration)
                    .region("region")
                    .build();
    
            ossClient.shutdown();
        }
    }

使用OIDCRoleARN

Container ServiceKubernetes版中設定了Worker節點RAM角色後,對應節點內的Pod中的應用也就可以像ECS上部署的應用一樣,通過中繼資料服務(Meta Data Server)擷取關聯角色的STS Token。但如果容器叢集上部署的是不可信的應用(比如部署您的客戶提交的應用,代碼也沒有對您開放),您可能並不希望它們能通過中繼資料服務擷取Worker節點關聯執行個體RAM角色的STS Token。為了避免影響雲上資源的安全,同時又能讓這些不可信的應用安全地擷取所需的STS Token,實現應用層級的許可權最小化,您可以使用RRSA(RAM Roles for Service Account)功能。該方式底層實現是STS Token。阿里雲容器叢集會為不同的應用Pod建立和掛載相應的服務賬戶OIDC Token檔案,並將相關配置資訊注入到環境變數中,Credentials工具通過擷取環境變數的配置資訊,調用STS服務的AssumeRoleWithOIDC介面換取綁定角色的STS Token。該方式無需您提供一個AK或STS Token,消除了手動維護AK或STS Token的風險。詳情請參見通過RRSA配置ServiceAccount的RAM許可權實現Pod許可權隔離

  1. 添加credentials依賴。

    <!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java -->
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>credentials-java</artifactId>
        <version>LATEST</version>
    </dependency>
  1. 配置OIDC的RAM角色作為訪問憑證。

    import com.aliyun.credentials.models.CredentialModel;
    import com.aliyun.oss.common.auth.Credentials;
    import com.aliyun.oss.common.auth.CredentialsProvider;
    import com.aliyun.oss.common.auth.DefaultCredentials;
    
    public class OidcRoleArnDemoTest {
        public static void main(String[] args) {
    
            com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config();
            // 指定Credential類型,固定值為oidc_role_arn
            config.setType("oidc_role_arn");
            // RAM角色名稱ARN,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定RoleArn
            config.setRoleArn("<RoleArn>");
            // OIDC供應商ARN,可以通過環境變數ALIBABA_CLOUD_OIDC_PROVIDER_ARN設定OidcProviderArn
            config.setOidcProviderArn("<OidcProviderArn>");
            // OIDC Token檔案路徑,可以通過環境變數ALIBABA_CLOUD_OIDC_TOKEN_FILE設定OidcTokenFilePath
            config.setOidcTokenFilePath("<OidcTokenFilePath>");
            // 角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定RoleSessionName
            config.setRoleSessionName("<RoleSessionName>");
            // 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
            config.setPolicy("<Policy>");
            // 設定session到期時間
            config.setRoleSessionExpiration(3600);
    
            final com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client(config);
    
            CredentialsProvider credentialsProvider = new CredentialsProvider(){
                @Override
                public void setCredentials(Credentials credentials) {
                }
    
                @Override
                public Credentials getCredentials() {
                    CredentialModel credential = credentialsClient.getCredential();
                    return  new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken());
                }
            };
            // 使用credentialsProvider初始化用戶端
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            // 顯式聲明使用 V4 簽名演算法
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);  
            // 建立OSSClient執行個體。
            OSS ossClient = OSSClientBuilder.create()
                    .endpoint("endpoint")
                    .credentialsProvider(credentialsProvider)
                    .clientConfiguration(clientBuilderConfiguration)
                    .region("region")
                    .build();
    
            ossClient.shutdown();
        }
    }

使用Function Compute上下文中的Credentials

如果您的應用程式的函數部署運行在Function Compute中,您可以使用Function Compute上下文中的Credentials初始化憑證提供者。該方式底層實現是STS Token。Function Compute根據函數配置的角色,通過扮演服務角色,而擷取一個STS Token,然後通過上下文中的參數Credentials將STS Token傳遞給您的應用程式。該STS Token的有效期間為36小時,且不支援修改。函數的最大執行時間為24小時,因此,執行函數過程中,STS Token不會到期,您無需考慮重新整理問題。該方式無需您提供一個AK或STS Token,消除了手動維護AK或STS Token的風險。如何授予Function Compute訪問OSS的許可權,請參見授予Function Compute訪問其他雲端服務的許可權

  1. 添加Function Compute上下文依賴。

    <!-- https://mvnrepository.com/artifact/com.aliyun.fc.runtime/fc-java-core -->
    <dependency>
        <groupId>com.aliyun.fc.runtime</groupId>
        <artifactId>fc-java-core</artifactId>
        <version>1.4.1</version>
    </dependency>
  2. 使用Function Compute上下文中的Credentials初始化憑證提供者。

    package example;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import com.aliyun.fc.runtime.Context;
    import com.aliyun.fc.runtime.Credentials;
    import com.aliyun.fc.runtime.StreamRequestHandler;
    import com.aliyun.oss.common.auth.CredentialsProvider;
    import com.aliyun.oss.common.auth.DefaultCredentialProvider;
    
    public class App implements StreamRequestHandler {
    
        @Override
        public void handleRequest(
            InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
    
            // 擷取密鑰資訊,執行前,確保函數所在的服務配置了角色資訊,並且角色需要擁有相關OSS許可權,建議直接使用AliyunFCDefaultRole角色
            Credentials creds = context.getExecutionCredentials();
    
            // 使用擷取到的憑證建立憑證提供者執行個體
            CredentialsProvider credentialsProvider = new DefaultCredentialProvider(creds.getAccessKeyId(), creds.getAccessKeySecret(), creds.getSecurityToken());
    
            // 使用credentialsProvider初始化用戶端
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            // 顯式聲明使用 V4 簽名演算法
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);  
            // 建立OSSClient執行個體。
            OSS ossClient = OSSClientBuilder.create()
                    .endpoint("endpoint")
                    .credentialsProvider(credentialsProvider)
                    .clientConfiguration(clientBuilderConfiguration)
                    .region("region")
                    .build();
    
            ossClient.shutdown();
    
            outputStream.write(new String("done").getBytes());
        }
    }

使用CredentialsURI

如果您的應用程式需要通過外部系統擷取阿里雲憑證,從而實現靈活的憑證管理和無密鑰訪問,您可以使用CredentialsURI初始化憑證提供者。該方式底層實現是STS Token。Credentials工具通過您提供的URI擷取STS Token,完成憑證用戶端初始化。該方式無需您提供一個AK或STS Token,消除了手動維護AK或STS Token的風險。

重要
  • 請注意,CredentialsURI指的是擷取STS Token的伺服器位址。

  • 提供CredentialsURI響應的後端服務需要實現STS Token的自動重新整理邏輯,確保您的應用程式始終能擷取到有效憑證。

  1. 為了使Credentials工具正確解析和使用STS Token,URI必須遵循以下響應協議:

    • 響應狀態代碼:200

    • 響應體結構:

      {
          "Code": "Success",
          "AccessKeySecret": "AccessKeySecret",
          "AccessKeyId": "AccessKeyId",
          "Expiration": "2021-09-26T03:46:38Z",
          "SecurityToken": "SecurityToken"
      }
  2. 添加credentials依賴。

    <!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java -->
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>credentials-java</artifactId>
        <version>LATEST</version>
    </dependency>
  3. 配置CredentialsURI作為訪問憑證。

    import com.aliyun.credentials.models.CredentialModel;
    import com.aliyun.oss.common.auth.Credentials;
    import com.aliyun.oss.common.auth.CredentialsProvider;
    import com.aliyun.oss.common.auth.DefaultCredentials;
    
    public class CredentialsUriDemoTest {
        public static void main(String[] args) {
    
            com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config();
            // 訪問憑證類型。固定為credentials_uri
            config.setType("credentials_uri");
            // 憑證的 URI,即您產生STS Token的伺服器位址,格式為http://local_or_remote_uri/,可以通過環境變數ALIBABA_CLOUD_CREDENTIALS_URI設定CredentialsUri
            config.setCredentialsUri("<CredentialsUri>");
    
            final com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client(config);
    
            CredentialsProvider credentialsProvider = new CredentialsProvider(){
                @Override
                public void setCredentials(Credentials credentials) {
                }
    
                @Override
                public Credentials getCredentials() {
                    CredentialModel credential = credentialsClient.getCredential();
                    return  new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken());
                }
            };
            // 使用credentialsProvider初始化用戶端
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            // 顯式聲明使用 V4 簽名演算法
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);  
            // 建立OSSClient執行個體。
            OSS ossClient = OSSClientBuilder.create()
                    .endpoint("endpoint")
                    .credentialsProvider(credentialsProvider)
                    .clientConfiguration(clientBuilderConfiguration)
                    .region("region")
                    .build();
    
            ossClient.shutdown();
        }
    }

使用自動輪轉的AK

如果您的應用程式需要長期訪問您的OSS,但部署啟動並執行環境面臨AK泄露的風險,需要頻繁手動輪轉(輪換)AK,您可以使用ClientKey初始化憑證提供者。該方式底層實現是AK。使用ClientKey後,Key Management Service(KMS)可以對託管的RAM使用者AK進行全自動的定期輪轉,將靜態RAM使用者AK動態化,從而降低AK泄漏的風險。除定期輪轉外,KMS還支援立即輪轉,在AK泄漏情況下快速更換AK。該方式無需您手動維護一個AK,從而降低安全性風險和維護複雜度增加的風險。如何擷取ClientKey,請參見建立應用存取點

  1. 添加憑據用戶端依賴。

    <!-- https://mvnrepository.com/artifact/com.aliyun/alibabacloud-secretsmanager-client -->
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>alibabacloud-secretsmanager-client</artifactId>
        <version>1.3.7</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-core -->
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-core</artifactId>
        <version>4.7.0</version>
    </dependency>
  2. 建立設定檔secretsmanager.properties

    # 訪問憑據類型,固定為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>"}]
  3. 使用設定檔來傳遞憑證資訊。

    import com.aliyun.oss.common.auth.Credentials;
    import com.aliyun.oss.common.auth.CredentialsProvider;
    import com.aliyun.oss.common.auth.DefaultCredentials;
    import com.aliyuncs.kms.secretsmanager.client.SecretCacheClient;
    import com.aliyuncs.kms.secretsmanager.client.SecretCacheClientBuilder;
    import com.aliyuncs.kms.secretsmanager.client.exception.CacheSecretException;
    import com.aliyuncs.kms.secretsmanager.client.model.SecretInfo;
    import org.codehaus.jettison.json.JSONException;
    import org.codehaus.jettison.json.JSONObject;
    
    public class ClientKeyDemoTest {
        public static void main(String[] args) throws CacheSecretException {
            final SecretCacheClient client = SecretCacheClientBuilder.newClient();
            CredentialsProvider credentialsProvider = new CredentialsProvider() {
                @Override
                public void setCredentials(Credentials credentials) {
                }
    
                @Override
                public Credentials getCredentials() {
                    try {
                        SecretInfo secretInfo = client.getSecretInfo("<secretName>");
                        JSONObject jsonObject = new JSONObject(secretInfo.getSecretValue());
    
                        String accessKeyId = jsonObject.getString("AccessKeyId");
                        String accessKeySecret = jsonObject.getString("AccessKeySecret");
    
                        return new DefaultCredentials(accessKeyId, accessKeySecret);
                    } catch (CacheSecretException | JSONException e) {
                        return null;
                    }
                }
            };
            // 使用credentialsProvider初始化用戶端
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            // 顯式聲明使用 V4 簽名演算法
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);  
            // 建立OSSClient執行個體。
            OSS ossClient = OSSClientBuilder.create()
                    .endpoint("endpoint")
                    .credentialsProvider(credentialsProvider)
                    .clientConfiguration(clientBuilderConfiguration)
                    .region("region")
                    .build();
    
            ossClient.shutdown();
        }
    }
    

使用自訂訪問憑證

如果以上憑證配置方式都不滿足要求時,您還可以通過實現Credential Providers介面的方式,來自訂憑證提供方式。需要注意,如果底層實現是STS Token,需要提供憑證的更新支援。

import com.aliyun.oss.common.auth.Credentials;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentials;

public class CustomCredentialProviderDemoTest {

    public static void main(String[] args) {

        CredentialsProvider credentialsProvider = new CredentialsProvider(){

            // 初始設定變數
            String accessKeyId = null;
            // 初始設定變數
            String accessKeySecrect = null;
            // 初始設定變數
            // String token = null;

            @Override
            public void setCredentials(Credentials credentials) {
            }

            @Override
            public Credentials getCredentials() {
                //TODO
                //自訂訪問憑證的擷取方法

                // 返回長期憑證 access_key_id, access_key_secrect  
                return new DefaultCredentials(accessKeyId, accessKeySecrect);

                // 返回 臨時憑證 access_key_id, access_key_secrect, token
                // 對於臨時憑證,需要根據到期時間,重新整理憑證。
                // return new DefaultCredentials(accessKeyId, accessKeySecrect, token);
            }
        };
        // 使用credentialsProvider初始化用戶端
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        // 顯式聲明使用 V4 簽名演算法
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);  
        // 建立OSSClient執行個體。
        OSS ossClient = OSSClientBuilder.create()
                .endpoint("endpoint")
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region("region")
                .build();

        ossClient.shutdown();
    }
}

使用預設憑據鏈

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

  1. 添加credentials依賴。

    <!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java -->
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>credentials-java</artifactId>
        <version>LATEST</version>
    </dependency>
  2. 配置Credentials作為訪問憑證。

    import com.aliyun.credentials.models.CredentialModel;
    import com.aliyun.oss.*;
    import com.aliyun.oss.common.auth.Credentials;
    import com.aliyun.oss.common.auth.CredentialsProvider;
    import com.aliyun.oss.common.auth.DefaultCredentials;
    
    public class Demo {
        public static void main(String[] args) {
            com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client();
            CredentialsProvider credentialsProvider = new CredentialsProvider(){
                @Override
                public void setCredentials(Credentials credentials) {
                }
    
                @Override
                public Credentials getCredentials() {
                    CredentialModel credential = credentialsClient.getCredential();
                    return  new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken());
                }
            };
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            // 顯式聲明使用 V4 簽名演算法
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);  
            // 使用credentialsProvider初始化用戶端
            // 建立OSSClient執行個體。
            OSS ossClient = OSSClientBuilder.create()
                    .endpoint("endpoint")
                    .credentialsProvider(credentialsProvider)
                    .clientConfiguration(clientBuilderConfiguration)
                    .region("region")
                    .build();
            ossClient.shutdown();
        }
    }

常見問題

在使用通過STS服務擷取的臨時身份憑證去初始化憑證提供者時,誤使用RAM使用者的AK

當您使用通過STS服務擷取的臨時身份憑證(Access Key ID、Access Key Secret和Security Token)初始化訪問憑證時,請勿混淆STS服務返回的AK與RAM使用者的AK,STS對應的AK是以STS開頭,樣本如下:

image

如何查看RAM使用者的AK?是否可以查看舊的AccessKey Secret?

  1. 如需查看RAM使用者的AK,請直接參考文檔查看RAM使用者的AccessKey資訊

  2. RAM使用者的AccessKey Secret僅在建立時顯示,之後無法查看,若您已經遺忘了的話無法找回。您可以直接存取RAM控制台選擇具體使用者,並建立新的AccessKey進行輪換。詳細請參見建立AccessKey

使用RAM使用者的AK進行上傳檔案時,報錯AccessDenied如何排查?

上傳檔案時出現AccessDenied的問題,通常是因為使用了錯誤的AK資訊或沒有給RAM使用者添加上傳檔案的許可權,您可以按照以下步驟檢查:

  1. 檢查您使用的RAM使用者的AK是否正確,請直接參考文檔查看RAM使用者的AccessKey資訊

  2. RAM使用者的AccessKey Secret僅在建立時顯示,之後無法查看,若您已經遺忘了的話無法找回。您可以直接存取RAM控制台選擇具體使用者,並建立新的AccessKey進行輪換。詳細請參見建立AccessKey

  3. 登入RAM控制台選擇具體使用者,給RAM使用者添加上傳檔案到OSS的許可權。

在使用外網Endpoint訪問OSS時,報錯無法串連該如何排查?

出現外網Endpoint無法串連的問題,通常是因為使用了錯誤的Endpoint地址或Bucket所在地區與請求的Endpoint不匹配。請您按照以下步驟檢查:

  1. 確認Bucket所在地區:登入阿里雲控制台,找到您的Bucket,確認其所在地區。

  2. 使用正確的Endpoint:根據Bucket所在地區,使用對應的外網Endpoint。例如,如果Bucket位於華東1(杭州),則應使用oss-cn-hangzhou.aliyuncs.com。各地區的Endpoint資訊請參見OSS地區和訪問網域名稱

  3. 檢查網路連接:確保您的網路環境可以正常訪問互連網,避免因網路問題導致串連失敗。

如果遇到報錯問題該如何查詢具體的錯誤類型?

關於錯誤類型的查詢,OSS文檔提供了EC錯誤碼供您參閱,例如關於認證方面的常見報錯問題,請參見02-AUTH