go - 如何使用 AWS SDK Go v2 将 AWS STS Assume 角色与 MFA 结合使用?
问题描述
这是我想要做的。我有 2 个 AWS 账户 A 和 B。使用适用于 Go v2 的 AWS 开发工具包我想使用带有 Acct A 凭证的 CLI 配置文件,并在账户 B 中担任需要 MFA 的角色。
我已经阅读了 config 和 stscreds 的包文档https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/stscreds。它是如此令人困惑的问题(编译错误)。我尝试了https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials@v1.2.0/stscreds以及您在代码中看到的,但是下面的行错误。
cfg.Credentials = &aws.CredentialsCache{Provider: creds}
错误:aws.CredentialsCache 类型的结构文字中的未知字段“Provider”
这是我到目前为止所拥有的。
package main
import (
"context"
"log"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sts"
)
func main() {
region := "us-west-2"
profile := "acctacliprofile"
roleToAssume := "arn:aws:iam::accountB:role/TestRole"
externalID := "TestingOnly"
mfaSerial := "arn:aws:iam::acctA:mfa/user"
ctx := context.TODO()
cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region),
config.WithSharedConfigProfile(profile))
if err != nil {
log.Fatal(err)
}
creds := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), roleToAssume, func(o
*stscreds.AssumeRoleOptions) {
o.SerialNumber = aws.String(mfaSerial)
o.ExternalID = aws.String(externalID)
o.TokenProvider = stscreds.StdinTokenProvider
})
c, err := creds.Retrieve(ctx)
if err != nil {
log.Fatal(err)
}
log.Printf("%T\n", c)
log.Printf("%v\n", c.AccessKeyID)
log.Printf("%v\n", c.SecretAccessKey)
log.Printf("%v\n", c.SessionToken)
}
这基本上有效,要求提供 MFA 令牌并假设角色成功,但是我如何使用这些凭据来创建服务客户端等,因为 cfg 是使用本地 cli 配置文件创建的,并且我想使用临时凭据来进行服务调用。
由于文档中的以下代码失败,我如何使用新凭据更新 cfg 并使用凭据进行 s3 或其他服务调用。
cfg.Credentials = &aws.CredentialsCache{Provider: creds}
// Create service client value configured for credentials
// from assumed role.
svc := s3.NewFromConfig(cfg)
希望新的 AWS Go SDK v2 的文档没有太多不足之处。
谢谢你的帮助。
解决方案
最终使用Go SDK v2工作的代码
go version go1.15.11 darwin/amd64
去.mod
module stsassumerolemfav2
go 1.15
require (
github.com/aws/aws-sdk-go-v2 v1.5.0
github.com/aws/aws-sdk-go-v2/config v1.2.0
github.com/aws/aws-sdk-go-v2/credentials v1.2.0
github.com/aws/aws-sdk-go-v2/service/sns v1.4.0
github.com/aws/aws-sdk-go-v2/service/sts v1.4.0
)
main.go
import (
"context"
"log"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sns"
"github.com/aws/aws-sdk-go-v2/service/sts"
)
func main(){
region := "region" //add region
profile := "cli-profile" //add cli profile account A
roleToAssume := "arn:aws:iam::acctB:role/TestRole"
externalID := "TestingOnly"
mfaSerial := "arn:aws:iam::acctA:mfa/usermfadevice"
ctx := context.TODO()
cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region), config.WithSharedConfigProfile(profile))
if err != nil {
log.Fatal(err)
}
// Create the credentials from AssumeRoleProvider to assume the role
// referenced by the "myRoleARN" ARN using the MFA token code provided.
creds := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), roleToAssume, func(o *stscreds.AssumeRoleOptions) {
o.SerialNumber = aws.String(mfaSerial)
o.ExternalID = aws.String(externalID)
o.TokenProvider = stscreds.StdinTokenProvider
})
cfg.Credentials = aws.NewCredentialsCache(creds)
// Create service client value configured for credentials from assumed role.
//Note: Not checking NextToken since test results are small dataset and do not need pagination.
snsclient := sns.NewFromConfig(cfg)
lti := &sns.ListTopicsInput{}
lto, err := snsclient.ListTopics(ctx, lti)
if err != nil {
log.Println(err)
}
if lto != nil {
for _, t := range lto.Topics {
log.Println(*t.TopicArn)
}
}
}
推荐阅读
- docker - 如何在 if 语句中更改 docker ARG 值?
- angular - 调用 HTTP.post() 角度时表单数据为空
- java - 如何使用 Olingo v2 和 Java 发出 $batch POST 请求
- apache-camel - Camel JPA 组件路由未完全执行
- r - 如何在 R Markdown 中水平绘制决策树?
- python - Python math.floor 计算错误
- javascript - 如何为网站提供离线支持
- sql-loader - 使用 sqlldr 插入具有批处理 ID 的行
- react-native - 反应导航嵌套在 StackNavigator 中的一个屏幕上的两个导航器
- rest - 使用带有 Symfony 3.4 的 FOSRestBundle 为多个 REST 控制器进行路由