客户端初始化和请求方式

更新时间:

在使用阿里云SDK调用OpenAPI操作资源时,必须正确配置凭证信息。Java V1.0 SDK支持多种凭据配置方式,本文详细阐述了如何配置访问凭据,以确保安全有效地使用SDK进行开发。

客户端初始化方式

  • 使用AccessKey

    阿里云账号和RAM用户可以生成用于调用OpenAPI的AccessKey密钥对,您可以使用该AccessKey初始化客户端。

    重要

    由于主账号AccessKey有资源完全的权限,一旦泄露风险巨大。建议您使用RAM用户的AccessKey,并设置定期轮换,创建RAM用户AccessKey的方法请参见创建AccessKey

    package main
    
    import (
    	"os"
    
    	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
    )
    
    func main() {
    	// 使用AccessKey初始化SDK客户端
            // 这里通过环境变量获取RAM用户的AccessKey ID和AccessKey Secret,以避免硬编码带来的安全风险
    	client, err := sdk.NewClientWithAccessKey("<regionId>", os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
    }
    
  • 使用STS Token

    通过安全令牌服务(Security Token Service,简称 STS),申请临时安全凭证(Temporary Security Credentials,简称 TSC),创建临时安全客户端。

    package main
    
    import (
    	"os"
    
    	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
    )
    
    func main() {
    	// 使用STS(Security Token Service)令牌创建SDK客户端
    	// 这种方式适用于需要临时访问权限的场景,比如ECI(Elastic Container Instance)
    	client, err := sdk.NewClientWithStsToken("<regionId>", os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"), os.Getenv("ALIBABA_CLOUD_SECURITY_TOKEN"))
    }
  • 使用RamRoleArn

    通过指定RAM角色的ARN(Alibabacloud Resource Name)来初始化客户端。其底层实现逻辑是客户端在发起请求前,先调用STS服务获取STS Token。

    package main
    
    import (
        "os"
    
        "github.com/aliyun/alibaba-cloud-sdk-go/sdk"
    )
    
    func main() {
        // 使用SDK创建一个客户端实例,该实例使用RAM角色ARN进行身份验证
        // "<regionId>":指定SDK客户端要访问的阿里云区域ID
        // os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"):从环境变量中获取RAM用户AccessKey ID
        // os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"):从环境变量中获取RAM用户AccessKey Secret
        // "<roleArn>":指定要扮演的RAM角色的ARN
        // "<roleSessionName>":指定角色会话的名称,用于标识和区分不同的会话
        client, err := sdk.NewClientWithRamRoleArn("<regionId>", os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"), "<roleArn>", "<roleSessionName>")
    }
    
  • 使用RamRoleArn(自定义权限)

    如果您想限制生成的STS Token的权限,您可以自定义权限策略来初始化客户端。

    package main
    
    import (
    	"os"
    
    	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
    )
    
    func main() {
    	// 使用SDK创建一个客户端实例,该实例使用RAM角色ARN和自定义策略进行认证
    	// "<regionId>":指定SDK客户端要访问的阿里云区域ID
    	// os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"):从环境变量中获取RAM用户AccessKey ID
    	// os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"):从环境变量中获取RAM用户AccessKey Secret
    	// "<roleArn>":指定要扮演的RAM角色的ARN
    	// "<roleSessionName>":指定角色会话的名称,用于标识和区分不同的会话
    	// "<policy>":指定一个自定义的授权策略,用于限制角色会话的权限
    	client, err := sdk.NewClientWithRamRoleArnAndPolicy("<regionId>", os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
    		os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"), "<roleArn>", "<roleSessionName>", "<policy>")
    }
  • 使用ECS实例RAM角色

    通过使用ECS实例绑定的RAM角色名称,调用ECS的元数据服务(Metadata Server)获取STS Token,完成客户端初始化。

    package main
    
    import (
    	"os"
    
    	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
    )
    
    func main() {
        // 通过ECS实例的RAM角色来获取访问凭证,从而创建一个阿里云客户端
        // 它适用于那些需要在ECS实例上运行,并且需要访问其他阿里云资源的程序
        // 参数"<regionId>"指定客户端要访问的阿里云区域,"<roleName>"指定要使用的RAM角色名称
        client, err := sdk.NewClientWithEcsRamRole("<regionId>", "<roleName>")
    }
    
  • 使用OIDCRoleArn

    在容器服务Kubernetes版中配置了Worker节点RAM角色后,您可以基于RRSA功能在集群内实现Pod级别的应用关联RAM角色功能。各个应用可以独立扮演不同的RAM角色,并利用获取的临时凭证访问云资源,从而实现应用RAM权限的最小化,并满足无AccessKey访问阿里云OpenAPI的需求,以避免AccessKey泄露。

    阿里云容器集群会为不同的应用Pod创建和挂载相应的服务账户OIDC Token文件,并将相关配置信息注入到环境变量中,Credentials工具通过获取环境变量的配置信息,调用STS服务的AssumeRoleWithOIDC - OIDC角色SSO时获取扮演角色的临时身份凭证接口换取绑定角色的STS Token。详情请参见通过RRSA配置ServiceAccount的RAM权限实现Pod权限隔离

    package main
    
    import (
    	"os"
    
    	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
    	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
    )
    
    func main() {
    	config := sdk.NewConfig()
    
    	// 使用OIDCRoleArn初始化SDK客户端
    	oidcProvider, _ := credentials.NewOIDCCredentialsProviderBuilder().
    		// OIDC提供商ARN,可以通过环境变量ALIBABA_CLOUD_OIDC_PROVIDER_ARN设置OIDCProviderARN
    		WithOIDCProviderARN(os.Getenv("ALIBABA_CLOUD_OIDC_PROVIDER_ARN")).
    		// OIDC Token文件路径,可以通过环境变量ALIBABA_CLOUD_OIDC_TOKEN_FILE设置OIDCTokenFilePath
    		WithOIDCTokenFilePath(os.Getenv("ALIBABA_CLOUD_OIDC_TOKEN_FILE")).
    		// RAM角色名称ARN,可以通过环境变量ALIBABA_CLOUD_ROLE_ARN设置RoleArn
    		WithRoleArn(os.Getenv("ALIBABA_CLOUD_ROLE_ARN")).
    		// 自定义角色会话名称
    		WithRoleSessionName("<RoleSessionName>").
    		// 设置更小的权限策略,非必填。示例值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
    		WithPolicy("<Policy>").
    		// 设置session过期时间
    		WithDurationSeconds(3600).
    		Build()
    
    	client, err := sdk.NewClientWithOptions("cn-beijing", config, oidcProvider)
    }
    
  • 使用Bearer Token

    目前只有云呼叫中心CCC这款产品支持Bearer Token的凭据初始化方式。

    package main
    
    import (
    	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
    )
    
    func main() {
        // 使用Bearer Token初始化SDK客户端
        // regionId用于指定服务的地域,bearerToken是一种认证方式,用于授权访问API
        client, err := sdk.NewClientWithBearerToken("<regionId>", "<bearerToken>")
    }
  • 使用默认凭证链创建客户端

    当您在初始化凭据客户端不传入任何参数时,将使用默认凭证提供程序链创建客户端,也可以自定义程序链。可通过自定义程序链代替默认程序链的寻找顺序,也可以自行编写闭包传入提供者。

    package main
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/sdk"
        "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider"
    )
    
    func main() {
        ProviderEnv := provider.NewEnvProvider()
        ProviderProfile := provider.NewProfileProvider()
        ProviderInstance := provider.NewInstanceCredentialsProvider()
    
        // 可以自定义凭据程序链代替默认凭证程序链,默认顺序为ProviderEnv, ProviderProfile, ProviderInstance
        client, err := sdk.NewClientWithProvider("<regionId>", ProviderInstance, ProviderProfile, ProviderEnv)
    }

    默认凭证提供程序链查找可用的客户端,寻找顺序如下:

    程序首先会在环境变量里寻找环境凭证,如果定义了 ALIBABA_CLOUD_ACCESS_KEY_IDALIBABA_CLOUD_ACCESS_KEY_SECRET 环境变量且不为空,程序将使用它们创建默认客户端。如果请求指定的客户端不是默认客户端,程序会在配置文件中加载和寻找客户端。

    如果用户主目录存在默认文件 ~/.alibabacloud/credentials (Windows 为 C:\Users\USER_NAME\.alibabacloud\credentials),程序会自动创建指定类型和名称的客户端。默认文件可以不存在,但解析错误会抛出异常。 客户端名称不分大小写,若客户端同名,后者会覆盖前者。也可以手动加载指定文件: AlibabaCloud::load('/data/credentials', 'vfs://AlibabaCloud/credentials', ...); 不同的项目、工具之间可以共用这个配置文件,因为超出项目之外,也不会被意外提交到版本控制。Windows 上可以使用环境变量引用到主目录 %UserProfile%。类 Unix 的系统可以使用环境变量 $HOME 或 ~ (tilde)。 可以通过定义 ALIBABA_CLOUD_CREDENTIALS_FILE 环境变量修改默认文件的路径。

    [default]                          # 默认客户端
    type = access_key                  # 认证方式为 access_key
    access_key_id = foo                # Key
    access_key_secret = bar            # Secret
    
    [client1]                          # 命名为 `client1` 的客户端
    type = ecs_ram_role                # 认证方式为 ecs_ram_role
    role_name = EcsRamRoleTest         # Role Name
    
    [client2]                          # 命名为 `client2` 的客户端
    type = ram_role_arn                # 认证方式为 ram_role_arn
    access_key_id = foo
    access_key_secret = bar
    role_arn = role_arn
    role_session_name = session_name

    如果定义了环境变量 ALIBABA_CLOUD_ECS_METADATA 且不为空,程序会将该环境变量的值作为角色名称,请求 http://100.100.100.200/latest/meta-data/ram/security-credentials/ 获取临时安全凭证,并创建一个默认客户端。

  • 创建带运行时参数的客户端

    客户端初始化还支持配置运行时参数,包含代理配置、超时配置、重试机制配置、启用异步调用等。

    package main
    
    import (
    	"fmt"
    	"os"
    
    	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
    	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
    )
    
    func main() {
    	// 配置运行时参数
    	config := sdk.NewConfig()
    	// 使用RAM用户AccessKeyID和AccessKeySecret
    	credential := credentials.NewAccessKeyCredential(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
    	client, err := sdk.NewClientWithOptions("<regionId>", config, credential)
    	if err != nil {
    		panic(err)
    	}

请求方式

使用CommonRequest进行调用

只需核心包即可发起调用,无需安装各云产品的SDK。通过CommonRequest构造请求参数,调用ProcessCommonRequest函数发起请求。更多详情,请参见使用CommonRequest进行调用

使用云产品SDK提供的特化调用

需要安装云产品SDK,云产品获取方式:

  1. 访问SDK 中心

  2. 在顶部菜单栏选择云产品,例如选择云服务器ECS。

  3. 选择API 版本,如果云产品有多个版本,请选择推荐版本或者最新版本。

  4. 选择SDK 版本,选择V1.0

  5. 所有语言中选择Go

  6. 安装方式中复制命令到终端执行。

go get github.com/aliyun/alibaba-cloud-sdk-go/services/ecs

调用示例

package main

import (
	"fmt"

	"os"

	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
	ecs "github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
)

func main() {
	// 配置运行时参数
	config := sdk.NewConfig()
	// 使用RAM用户AccessKeyID和AccessKeySecret
	credential := credentials.NewAccessKeyCredential(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
	client, err := ecs.NewClientWithOptions("cn-hangzhou", config, credential)
	if err != nil {
		panic(err)
	}
	// 使用云产品SDK提供的Request对象
	request := ecs.CreateDescribeRegionsRequest()
	request.Scheme = "https" // 设置请求协议
	// 请求参数
	request.InstanceChargeType = "PrePaid" // 实例的计费方式
	request.ResourceType = "instance" // 资源类型
	// 发起请求并获取返回值
	response, err := client.DescribeRegions(request)
	if err != nil {
		fmt.Print(err.Error())
	}
	fmt.Printf("response is %#v\n", response)
}