本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。
使用Go SDK发起OSS请求,您需要配置访问凭证。阿里云服务会通过访问凭证验证您的身份信息和访问权限。您可以根据使用场景对认证和授权的要求,选择不同类型的访问凭证。本文介绍如何配置临时访问凭证和长期访问凭证。
前提条件
在配置访问凭证前,您需要安装Go SDK。详情请参见安装。
初始化凭证提供者
凭证提供者选型
OSS支持多种方式初始化凭证提供者,您可以根据使用场景对认证和授权的要求,选择对应的方式初始化凭证提供者。
凭证提供者初始化方式 | 适用场景 | 是否需要提供前置的AK或STS Token | 底层实现基于的凭证 | 凭证有效期 | 凭证轮转或刷新方式 |
部署运行在安全、稳定且不易受外部攻击的环境的应用程序,无需频繁轮转凭证就可以长期访问云服务 | 是 | AK | 长期 | 手动轮转 | |
部署运行在不可信的环境的应用程序,希望能控制访问的有效期、权限 | 是 | STS Token | 临时 | 手动刷新 | |
需要授权访问云服务,例如跨阿里云账号访问云服务的应用程序 | 是 | STS Token | 临时 | 自动刷新 | |
部署运行在阿里云的ECS实例、ECI实例、容器服务Kubernetes版的Worker节点中的应用程序 | 否 | STS Token | 临时 | 自动刷新 | |
部署运行在阿里云的容器服务Kubernetes版的Worker节点中的不可信应用程序 | 否 | STS Token | 临时 | 自动刷新 | |
部署运行在阿里云函数计算中的应用程序的函数 | 否 | STS Token | 临时 | 无需刷新 | |
需要通过外部系统获取访问凭证的应用程序 | 否 | STS Token | 临时 | 自动刷新 | |
部署运行在面临AK泄露风险的环境的应用程序,需要频繁轮转凭证才长期能访问云服务 | 否 | AK | 长期 | 自动轮转 | |
如果以上凭证配置方式都不满足要求时,您可以自定义获取凭证的方式 | 自定义 | 自定义 | 自定义 | 自定义 |
方式一:使用AK
如果您的应用程序部署运行在安全、稳定且不易受外部攻击的环境中,需要长期访问您的OSS,且不能频繁轮转凭证时,您可以使用阿里云主账号或RAM用户的AK(Access Key ID、Access Key Secret)初始化凭证提供者。需要注意的是,该方式需要您手动维护一个AK,存在安全性风险和维护复杂度增加的风险。如何获取AK,请参见CreateAccessKey - 创建主账号或RAM用户访问密钥。
环境变量
阿里云账号拥有资源的全部权限,AK一旦泄露,会给系统带来巨大风险,不建议使用。推荐使用最小化授权的RAM用户的AK。
使用AK设置环境变量。
Mac OS X/Linux/Unix
export OSS_ACCESS_KEY_ID=<ALIBABA_CLOUD_ACCESS_KEY_ID> export OSS_ACCESS_KEY_SECRET=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
Windows
set OSS_ACCESS_KEY_ID=<ALIBABA_CLOUD_ACCESS_KEY_ID> set OSS_ACCESS_KEY_SECRET=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
使用环境变量来传递凭证信息。
package main import ( "fmt" "os" "github.com/aliyun/aliyun-oss-go-sdk/oss" ) func main() { // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 provider, err := oss.NewEnvironmentVariableCredentialsProvider() if err != nil { fmt.Println("Error:", err) os.Exit(-1) } // 创建OSSClient实例。 // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。 // yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。 clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)} clientOptions = append(clientOptions, oss.Region("yourRegion")) // 设置签名版本 clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4)) client, err := oss.New("yourEndpoint", "", "", clientOptions...) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } fmt.Printf("client:%#v\n", client) }
静态凭证
您可以在代码中使用变量来引用凭证,这些变量在运行时会被环境变量、配置文件或其他外部数据源中的实际凭证值填充。
以下操作步骤以配置文件为例。
需要安装go-ini
库。如果尚未安装,您可以使用以下命令安装:
go get -u github.com/go-ini/ini
创建配置文件
config.ini
。[credentials] alibaba_cloud_access_key_id = <ALIBABA_CLOUD_ACCESS_KEY_ID> alibaba_cloud_access_key_secret = <ALIBABA_CLOUD_ACCESS_KEY_SECRET>
使用配置文件来传递凭证信息。
package main import ( "fmt" "os" "github.com/aliyun/aliyun-oss-go-sdk/oss" "gopkg.in/ini.v1" ) type defaultCredentials struct { config *oss.Config } func (defCre *defaultCredentials) GetAccessKeyID() string { return defCre.config.AccessKeyID } func (defCre *defaultCredentials) GetAccessKeySecret() string { return defCre.config.AccessKeySecret } func (defCre *defaultCredentials) GetSecurityToken() string { return defCre.config.SecurityToken } type defaultCredentialsProvider struct { config *oss.Config } func (defBuild *defaultCredentialsProvider) GetCredentials() oss.Credentials { return &defaultCredentials{config: defBuild.config} } func NewDefaultCredentialsProvider(accessID, accessKey, token string) (defaultCredentialsProvider, error) { var provider defaultCredentialsProvider if accessID == "" { return provider, fmt.Errorf("access key id is empty!") } if accessKey == "" { return provider, fmt.Errorf("access key secret is empty!") } config := &oss.Config{ AccessKeyID: accessID, AccessKeySecret: accessKey, SecurityToken: token, } return defaultCredentialsProvider{ config, }, nil } func main() { cfg, err := ini.Load("config.ini") if err != nil { fmt.Println("Error loading config file:", err) return } accessKeyID := cfg.Section("credentials").Key("alibaba_cloud_access_key_id").String() accessKeySecret := cfg.Section("credentials").Key("alibaba_cloud_access_key_secret").String() provider, err := NewDefaultCredentialsProvider(accessKeyID, accessKeySecret, "") if err != nil { fmt.Println("Error:", err) os.Exit(-1) } // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。 // yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。 clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)} clientOptions = append(clientOptions, oss.Region("yourRegion")) // 设置签名版本 clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4)) client, err := oss.New("yourEndpoint", "", "", clientOptions...) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } fmt.Printf("client:%#v\n", client) }
方式二:使用STS Token
如果您的应用程序需要临时访问OSS,您可以使用通过STS服务获取的临时身份凭证(Access Key ID、Access Key Secret和Security Token)初始化凭证提供者。需要注意的是,该方式需要您手动维护一个STS Token,存在安全性风险和维护复杂度增加的风险。此外,如果您需要多次临时访问OSS,您需要手动刷新STS Token。如何获取STS Token,请参见AssumeRole - 获取扮演角色的临时身份凭证。
使用临时身份凭证设置环境变量。
Mac OS X/Linux/Unix
export OSS_ACCESS_KEY_ID=<ALIBABA_CLOUD_ACCESS_KEY_ID> export OSS_ACCESS_KEY_SECRET=<ALIBABA_CLOUD_ACCESS_KEY_SECRET> export OSS_SESSION_TOKEN=<ALIBABA_CLOUD_SECURITY_TOKEN>
Windows
set OSS_ACCESS_KEY_ID=<ALIBABA_CLOUD_ACCESS_KEY_ID> set OSS_ACCESS_KEY_SECRET=<ALIBABA_CLOUD_ACCESS_KEY_SECRET> set OSS_SESSION_TOKEN=<ALIBABA_CLOUD_SECURITY_TOKEN>
通过环境变量来传递凭证信息。
package main import ( "fmt" "os" "github.com/aliyun/aliyun-oss-go-sdk/oss" ) func main() { // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET,OSS_SESSION_TOKEN。 provider, err := oss.NewEnvironmentVariableCredentialsProvider() if err != nil { fmt.Println("Error:", err) os.Exit(-1) } // 创建OSSClient实例。 // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。 // yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。 clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)} clientOptions = append(clientOptions, oss.Region("yourRegion")) // 设置签名版本 clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4)) client, err := oss.New("yourEndpoint", "", "", clientOptions...) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } fmt.Printf("client:%#v\n", client) }
方式三:使用RAMRoleARN
如果您的应用程序需要授权访问OSS,例如跨阿里云账号访问OSS,您可以使用RAMRoleARN初始化凭证提供者。该方式底层实现是STS Token。通过指定RAM角色的ARN(Alibabacloud Resource Name),Credentials工具会前往STS服务获取STS Token,并在会话到期前自动刷新STS Token。此外,您还可以通过为policy
赋值来限制RAM角色到一个更小的权限集合。需要注意的是,该方式需要您提供一个AK,存在安全性风险和维护复杂度增加的风险。如何获取AK,请参见CreateAccessKey - 为RAM用户创建访问密钥。如何获取RAMRoleARN,请参见CreateRole - 创建角色。
添加credentials依赖。
go get github.com/aliyun/credentials-go/credentials
配置访问凭证。
package main import ( "fmt" "os" "github.com/aliyun/aliyun-oss-go-sdk/oss" "github.com/aliyun/credentials-go/credentials" ) type Credentials struct { AccessKeyId string AccessKeySecret string SecurityToken string } type defaultCredentialsProvider struct { cred credentials.Credential } func (credentials *Credentials) GetAccessKeyID() string { return credentials.AccessKeyId } func (credentials *Credentials) GetAccessKeySecret() string { return credentials.AccessKeySecret } func (credentials *Credentials) GetSecurityToken() string { return credentials.SecurityToken } func (defBuild *defaultCredentialsProvider) GetCredentials() oss.Credentials { cred, _ := defBuild.cred.GetCredential() return &Credentials{ AccessKeyId: *cred.AccessKeyId, AccessKeySecret: *cred.AccessKeySecret, SecurityToken: *cred.SecurityToken, } } func NewRamRoleArnCredentialsProvider(credential credentials.Credential) defaultCredentialsProvider { return defaultCredentialsProvider{ cred: credential, } } func main() { config := new(credentials.Config). // 填写Credential类型,固定值为ram_role_arn。 SetType("ram_role_arn"). // 从环境变量中获取RAM用户的访问密钥(AccessKeyId和AccessKeySecret)。 SetAccessKeyId(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")). SetAccessKeySecret(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")). // 以下操作默认直接填入参数数值,您也可以通过添加环境变量,并使用os.Getenv("<变量名称>")的方式来set对应参数 // 从环境变量中获取RAM角色的ARN信息,即需要扮演的角色ID。格式为acs:ram::$accountID:role/$roleName。 SetRoleArn("ALIBABA_CLOUD_ROLE_ARN"). // RoleArn默认环境变量规范名称ALIBABA_CLOUD_ROLE_ARN // 自定义角色会话名称,用于区分不同的令牌。 SetRoleSessionName("ALIBABA_CLOUD_ROLE_SESSION_NAME"). // RoleSessionName默认环境变量规范名称ALIBABA_CLOUD_ROLE_SESSION_NAME // (可选)限制STS Token权限。 SetPolicy(""). // (可选)限制STS Token的有效时间。 SetRoleSessionExpiration(3600) arnCredential, err := credentials.NewCredential(config) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } provider := NewRamRoleArnCredentialsProvider(arnCredential) // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。 // yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。 clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)} clientOptions = append(clientOptions, oss.Region("yourRegion")) // 设置签名版本 clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4)) client, err := oss.New("yourEndpoint", "", "", clientOptions...) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } fmt.Printf("client:%#v\n", client) }
方式四:使用ECSRAMRole
如果您的应用程序运行在ECS实例、ECI实例、容器服务Kubernetes版的Worker节点中,建议您使用ECSRAMRole初始化凭证提供者。该方式底层实现是STS Token。ECSRAMRole允许您将一个角色关联到ECS实例、ECI实例或容器服务 Kubernetes 版的Worker节点,实现在实例内部自动刷新STS Token。该方式无需您提供一个AK或STS Token,消除了手动维护AK或STS Token的风险。如何获取ECSRAMRole,请参见CreateRole - 创建角色。
添加credentials依赖。
go get github.com/aliyun/credentials-go/credentials
配置ECSRAMRole作为访问凭证。
package main import ( "fmt" "os" "github.com/aliyun/aliyun-oss-go-sdk/oss" "github.com/aliyun/credentials-go/credentials" ) type Credentials struct { AccessKeyId string AccessKeySecret string SecurityToken string } type CredentialsProvider struct { cred credentials.Credential } func (credentials *Credentials) GetAccessKeyID() string { return credentials.AccessKeyId } func (credentials *Credentials) GetAccessKeySecret() string { return credentials.AccessKeySecret } func (credentials *Credentials) GetSecurityToken() string { return credentials.SecurityToken } func (defBuild CredentialsProvider) GetCredentials() oss.Credentials { cred, _ := defBuild.cred.GetCredential() return &Credentials{ AccessKeyId: *cred.AccessKeyId, AccessKeySecret: *cred.AccessKeySecret, SecurityToken: *cred.SecurityToken, } } func NewEcsCredentialsProvider(credential credentials.Credential) CredentialsProvider { return CredentialsProvider{ cred: credential, } } func main() { config := new(credentials.Config). // 指定Credential类型,固定值为ecs_ram_role。 SetType("ecs_ram_role"). // (可选项)指定角色名称。如果不指定,OSS会自动获取角色。强烈建议指定角色名称,以降低请求次数。 SetRoleName("RoleName") ecsCredential, err := credentials.NewCredential(config) if err != nil { return } provider := NewEcsCredentialsProvider(ecsCredential) // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。 // yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。 clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)} clientOptions = append(clientOptions, oss.Region("yourRegion")) // 设置签名版本 clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4)) client, err := oss.New("yourEndpoint", "", "", clientOptions...) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } fmt.Printf("client:%#v\n", client) }
方式五:使用OIDCRoleARN
在容器服务Kubernetes版中设置了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权限隔离。
添加credentials依赖。
go get github.com/aliyun/credentials-go/credentials
配置OIDC的RAM角色作为访问凭证。
package main import ( "fmt" "os" "github.com/aliyun/aliyun-oss-go-sdk/oss" "github.com/aliyun/credentials-go/credentials" ) type Credentials struct { AccessKeyId string AccessKeySecret string SecurityToken string } type CredentialsProvider struct { cred credentials.Credential } func (credentials *Credentials) GetAccessKeyID() string { return credentials.AccessKeyId } func (credentials *Credentials) GetAccessKeySecret() string { return credentials.AccessKeySecret } func (credentials *Credentials) GetSecurityToken() string { return credentials.SecurityToken } func (defBuild CredentialsProvider) GetCredentials() oss.Credentials { cred, _ := defBuild.cred.GetCredential() return &Credentials{ AccessKeyId: *cred.AccessKeyId, AccessKeySecret: *cred.AccessKeySecret, SecurityToken: *cred.SecurityToken, } } func NewOIDCRoleARNCredentialsProvider(credential credentials.Credential) CredentialsProvider { return CredentialsProvider{ cred: credential, } } func main() { config := new(credentials.Config). // 指定 OIDC 令牌的文件路径,用于存储 OIDC 令牌。 SetOIDCTokenFilePath(os.Getenv("ALIBABA_CLOUD_OIDC_TOKEN_FILE")). // 以下操作默认直接填入参数数值,您也可以通过添加环境变量,并使用os.Getenv("<变量名称>")的方式来set对应参数 // 指定Credential类型,固定值为oidc_role_arn。 SetType("oidc_role_arn"). // 指定 OIDC 提供者的 ARN(Amazon Resource Name),格式为 acs:ram::account-id:oidc-provider/provider-name。 SetOIDCProviderArn("acs:ram::113511544585****:oidc-provider/TestOidcProvider"). // OIDCProviderArn默认环境变量规范名称ALIBABA_CLOUD_OIDC_PROVIDER_ARN // 自定义角色会话名称,用于区分不同的令牌。 SetRoleSessionName("role_session_name"). // RoleSessionName默认环境变量规范名称ALIBABA_CLOUD_ROLE_SESSION_NAME // 填写角色的ARN信息,即需要扮演的角色ID。格式为acs:ram::113511544585****:oidc-provider/TestOidcProvider SetRoleArn("acs:ram::113511544585****:role/testoidc"). // RoleArn默认环境变量规范名称ALIBABA_CLOUD_ROLE_ARN // (可选)指定访问角色时要使用的策略。 SetPolicy(""). SetSessionExpiration(3600) oidcCredential, err := credentials.NewCredential(config) if err != nil { return } provider := NewOIDCRoleARNCredentialsProvider(oidcCredential) // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。 // yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。 clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)} clientOptions = append(clientOptions, oss.Region("yourRegion")) // 设置签名版本 clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4)) client, err := oss.New("yourEndpoint", "", "", clientOptions...) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } fmt.Printf("client:%#v\n", client) }
方式六:使用函数计算上下文中的Credentials
如果您的应用程序的函数部署运行在函数计算中,您可以使用函数计算上下文中的Credentials初始化凭证提供者。该方式底层实现是STS Token。函数计算根据函数配置的角色,通过扮演服务角色,而获取一个STS Token,然后通过上下文中的参数Credentials将STS Token传递给您的应用程序。该STS Token的有效期为36小时,且不支持修改。函数的最大执行时间为24小时,因此,执行函数过程中,STS Token不会过期,您无需考虑刷新问题。该方式无需您提供一个AK或STS Token,消除了手动维护AK或STS Token的风险。如何授予函数计算访问OSS的权限,请参见授予函数计算访问其他云服务的权限。
添加函数计算上下文依赖。
go get github.com/aliyun/fc-runtime-go-sdk/fc go get github.com/aliyun/fc-runtime-go-sdk/fccontext
使用函数计算上下文中的Credentials初始化凭证提供者。
package main import ( "context" "fmt" "github.com/aliyun/aliyun-oss-go-sdk/oss" "github.com/aliyun/fc-runtime-go-sdk/fc" "github.com/aliyun/fc-runtime-go-sdk/fccontext" ) type GetObjectContext struct { OutputRoute string `json:"outputRoute"` OutputToken string `json:"outputToken"` InputOssUrl string `json:"inputOssUrl"` } type StructEvent struct { GetObjectContext GetObjectContext `json:"getObjectContext"` } func HandleRequest(ctx context.Context, event StructEvent) error { endpoint := event.GetObjectContext.OutputRoute fctx, _ := fccontext.FromContext(ctx) client, err := oss.New(endpoint, fctx.Credentials.AccessKeyId, fctx.Credentials.AccessKeySecret, oss.SecurityToken(fctx.Credentials.SecurityToken)) if err != nil { return fmt.Errorf("client new error: %v", err) } fmt.Printf("client:%#v\n", client) return nil } func main() { fc.Start(HandleRequest) }
方式七:使用CredentialsURI
如果您的应用程序需要通过外部系统获取阿里云凭证,从而实现灵活的凭证管理和无密钥访问,您可以使用CredentialsURI初始化凭证提供者。该方式底层实现是STS Token。Credentials工具通过您提供的URI获取STS Token,完成凭证客户端初始化。该方式无需您提供一个AK或STS Token,消除了手动维护AK或STS Token的风险。需要注意的是,提供CredentialsURI响应的后端服务需要实现STS Token的自动刷新逻辑,确保您的应用程序始终能获取到有效凭证。
为了使Credentials工具正确解析和使用STS Token,URI必须遵循以下响应协议:
响应状态码:200
响应体结构:
{ "Code": "Success", "AccessKeySecret": "AccessKeySecret", "AccessKeyId": "AccessKeyId", "Expiration": "2021-09-26T03:46:38Z", "SecurityToken": "SecurityToken" }
添加credentials依赖。
go get github.com/aliyun/credentials-go/credentials
配置CredentialsURI作为访问凭证。
package main import ( "fmt" "os" "github.com/aliyun/aliyun-oss-go-sdk/oss" "github.com/aliyun/credentials-go/credentials" ) type Credentials struct { AccessKeyId string AccessKeySecret string SecurityToken string } type CredentialsProvider struct { cred credentials.Credential } func (credentials *Credentials) GetAccessKeyID() string { return credentials.AccessKeyId } func (credentials *Credentials) GetAccessKeySecret() string { return credentials.AccessKeySecret } func (credentials *Credentials) GetSecurityToken() string { return credentials.SecurityToken } func (defBuild CredentialsProvider) GetCredentials() oss.Credentials { cred, _ := defBuild.cred.GetCredential() return &Credentials{ AccessKeyId: *cred.AccessKeyId, AccessKeySecret: *cred.AccessKeySecret, SecurityToken: *cred.SecurityToken, } } func NewCredentialsUriCredentialsProvider(credential credentials.Credential) CredentialsProvider { return CredentialsProvider{ cred: credential, } } func main() { config := new(credentials.Config). // 指定Credential类型,固定值为credentials_uri。 SetType("credentials_uri"). // 指定 url 地址;您也可以通过设置环境变量,并使用"os.Getenv("<变量名称>")的方式进行参数传递。 // URLCredential默认环境变量规范名称ALIBABA_CLOUD_CREDENTIALS_URI SetURLCredential("http://127.0.0.1") uriCredential, err := credentials.NewCredential(config) if err != nil { return } provider := NewCredentialsUriCredentialsProvider(uriCredential) // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。 // yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。 clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)} clientOptions = append(clientOptions, oss.Region("yourRegion")) // 设置签名版本 clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4)) client, err := oss.New("yourEndpoint", "", "", clientOptions...) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } fmt.Printf("client:%#v\n", client) }
方式八:使用自动轮转的AK
如果您的应用程序需要长期访问您的OSS,但部署运行的环境面临AK泄露的风险,需要频繁手动轮转(轮换)AK,您可以使用ClientKey初始化凭证提供者。该方式底层实现是AK。使用ClientKey后,密钥管理服务(KMS)可以对托管的RAM用户AK进行全自动的定期轮转,将静态的RAM用户AK动态化,从而降低AK泄漏的风险。除定期轮转外,KMS还支持立即轮转,在AK泄漏情况下快速更换AK。该方式无需您手动维护一个AK,从而降低安全性风险和维护复杂度增加的风险。如何获取ClientKey,请参见创建应用接入点。
使用
go get
命令,在项目中使用凭据客户端。go get -u github.com/aliyun/aliyun-secretsmanager-client-go
创建配置文件
secretsmanager.properties
。# 访问凭据类型 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#"}]
构建客户端。
package main import ( "encoding/json" "fmt" "os" "github.com/aliyun/aliyun-oss-go-sdk/oss" "github.com/aliyun/aliyun-secretsmanager-client-go/sdk" ) type defaultCredentials struct { config *oss.Config } func (defCre *defaultCredentials) GetAccessKeyID() string { return defCre.config.AccessKeyID } func (defCre *defaultCredentials) GetAccessKeySecret() string { return defCre.config.AccessKeySecret } func (defCre *defaultCredentials) GetSecurityToken() string { return defCre.config.SecurityToken } type defaultCredentialsProvider struct { config *oss.Config } func (defBuild *defaultCredentialsProvider) GetCredentials() oss.Credentials { return &defaultCredentials{config: defBuild.config} } func NewDefaultCredentialsProvider(accessID, accessKey, token string) (defaultCredentialsProvider, error) { var provider defaultCredentialsProvider if accessID == "" { return provider, fmt.Errorf("access key id is empty!") } if accessKey == "" { return provider, fmt.Errorf("access key secret is empty!") } config := &oss.Config{ AccessKeyID: accessID, AccessKeySecret: accessKey, SecurityToken: token, } return defaultCredentialsProvider{ config, }, nil } func main() { client, err := sdk.NewClient() if err != nil { fmt.Println("Error:", err) os.Exit(-1) } secretInfo, err := client.GetSecretInfo("#secretName#") if err != nil { fmt.Println("Error:", err) os.Exit(-1) } fmt.Printf("SecretValue:%s\n", secretInfo.SecretValue) var m map[string]string err = json.Unmarshal([]byte(secretInfo.SecretValue), &m) if err != nil { fmt.Println("Error decoding JSON:", err) os.Exit(-1) } accessKeyId := m["AccessKeyId"] accessKeySecret := m["AccessKeySecret"] provider, err := NewDefaultCredentialsProvider(accessKeyId, accessKeySecret, "") if err != nil { fmt.Println("Error:", err) os.Exit(-1) } // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。 // yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。 clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)} clientOptions = append(clientOptions, oss.Region("yourRegion")) // 设置签名版本 clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4)) ossClient, err := oss.New("yourEndpoint", "", "", clientOptions...) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } fmt.Printf("client:%#v\n", ossClient) }
方式九:自定义访问凭证
如果以上凭证配置方式都不满足要求,您还可以通过实现Credential Providers接口的方式,来自定义凭证提供方式。
package main
import (
"fmt"
"os"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
type CustomerCredentialsProvider struct {
config *oss.Config
}
func NewCustomerCredentialsProvider() CustomerCredentialsProvider {
return CustomerCredentialsProvider{}
}
func (s CustomerCredentialsProvider) GetCredentials() oss.Credentials {
// 返回长期凭证
config := &oss.Config{
AccessKeyID: "id",
AccessKeySecret: "secret",
}
return &CustomerCredentialsProvider{
config,
}
// 返回临时凭证
//config := &oss.Config{
// AccessKeyID: "id",
// AccessKeySecret: "secret",
// SecurityToken: "token",
//}
//return &CustomerCredentialsProvider{
// config,
//}
}
func (s *CustomerCredentialsProvider) GetAccessKeyID() string {
return s.config.AccessKeyID
}
func (s *CustomerCredentialsProvider) GetAccessKeySecret() string {
return s.config.AccessKeySecret
}
func (s *CustomerCredentialsProvider) GetSecurityToken() string {
return s.config.SecurityToken
}
func main() {
provider := NewCustomerCredentialsProvider()
// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
// yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
// 设置签名版本
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
fmt.Printf("client:%#v\n", client)
}
后续步骤
配置访问凭证后,您需要初始化OSSClient。详情请参见初始化。