如何使用AWS SDK Go v2在AWS STS中使用MFA进行角色扮演?

huangapple go评论80阅读模式
英文:

How do I use AWS STS Assume role with MFA using AWS SDK Go v2?

问题

这是我要做的事情。我有两个 AWS 账户 A 和 B。使用 AWS SDK for Go v2,我想要使用一个带有 Acct A 凭证的 CLI 配置文件,并在需要 MFA 的 Account B 中扮演一个角色。

我已经阅读了有关配置和 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}

// 创建配置为从扮演角色获取凭证的服务客户端值。
svc := s3.NewFromConfig(cfg)

希望 AWS Go SDK v2 的文档不要留下太多问题。

感谢任何帮助。

英文:

Here is what I am trying to do. I have 2 AWS Accounts A and B. Using AWS SDK for Go v2 I want to use a CLI profile with credentials for Acct A and assume a role in Account B that requires MFA.

I have read through the package docs for config and stscreds https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/stscreds. It is so confusing host of issues (compile errors). I tried https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials@v1.2.0/stscreds as well as you see in the code, however the line below errors.

cfg.Credentials = &aws.CredentialsCache{Provider: creds} 

ERROR: unknown field 'Provider' in struct literal of type aws.CredentialsCache

Here is what I have so far.

    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)
}

This basically works, asks to provide the MFA token and assume role succeeds but how do I use these credentials to create service clients etc since cfg was created with the local cli profile, and I want to use the temporary credentials to make the service calls.

Since the code below from docs fail, how do I update cfg with the new credentials and make the s3 or other service calls with creds.

cfg.Credentials = &aws.CredentialsCache{Provider: creds}

// Create service client value configured for credentials
// from assumed role.
svc := s3.NewFromConfig(cfg)

Wish the docs for the new AWS Go SDK v2 didn't leave a lot to be desired.

Thanks for any help.

答案1

得分: 3

使用Go SDK v2的最终可行代码

go version go1.15.11 darwin/amd64

go.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" //添加区域
    profile := "cli-profile" //添加CLI配置文件账户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)
    }
    // 使用AssumeRoleProvider创建凭证以扮演角色
    // 使用提供的MFA令牌代码引用的"myRoleARN" ARN。
    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)
    // 创建配置为使用扮演角色的凭证的服务客户端值。
    // 注意:由于测试结果是小数据集且不需要分页,因此不检查NextToken。
    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)
        }
    }
}

以上是使用Go SDK v2的最终可行代码。

英文:

Code that finally works using Go SDK v2

go version go1.15.11 darwin/amd64

go.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)
}
}
}

huangapple
  • 本文由 发表于 2021年5月19日 22:59:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/67605787.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定