更改 AWS go SDK v2 中的默认身份验证方法

Duc*_*ppy 5 sdk go amazon-web-services aws-sdk

默认情况下,golang AWS SDK v2 将使用以下链来确定凭证:

  • 环境变量
  • 共享配置
  • ECS 任务角色(如果是 ECS 任务)
  • EC2 实例配置文件(如果在 EC2 上运行)

我遇到一种情况,我需要配置 SDK 以忽略前两个(特别是环境变量)...我们有一个 CI 工作流程,可以出于测试原因设置 AWS 环境变量,但我们有一项自动化服务我们的变更跟踪系统中的变更请求应该仅使用 ECS 或 EC2 凭证进行身份验证。我们用于访问变更请求的工具是用 go 编写的。

v1 SDK实际上有NewChainCredentials创建新链的功能,但在v2中没有了。阅读代码似乎表明可以创建新的凭证链,但我无法弄清楚如何仅使用 ECS 和 EC2 提供程序替换默认链。

有人做过这个吗?通过 Google 和 GitHub 搜索并没有找到任何看起来像我想要的东西 - 大多数情况下我发现用自定义提供程序替换默认链或向链添加新提供程序,但尝试使用这些方法来替换默认提供程序与我想要的连锁店没有成功。

wil*_*200 0

这是可能的,但是关于使用哪种过程来获取凭证的一些具体实现细节必须被带入您的代码中(这很糟糕)。sdk 在 github.com/aws/aws-sdk-go-v2/credentials 和子目录中定义了大量进程。

您可以在此处了解默认凭证链

仅 EC2 和 ECS 凭证链示例:

package main

import (
    "context"
    "fmt"
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds"
    "github.com/aws/aws-sdk-go-v2/credentials/endpointcreds"
    "log"
    "net/http"
    "os"

    "github.com/aws/aws-sdk-go-v2/config"
)

const (
    ecsContainerEndpoint = "http://169.254.170.2"
)

func ecsContainerURI(path string) string {
    return fmt.Sprintf("%s%s", ecsContainerEndpoint, path)
}

func main() {
    os.Setenv("AWS_SECRET_ACCESS_KEY", "TEST")
    os.Setenv("AWS_ACCESS_KEY_ID", "TEST")
    // ECS credentials are read from an endpoint that is passed through
    // environment variables
    // os.Setenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", "/v2")

    var provider aws.CredentialsProvider
    envConfig, _ := config.NewEnvConfig()
    switch {
    case len(envConfig.ContainerCredentialsRelativePath) != 0:
        provider = endpointcreds.New(ecsContainerURI(envConfig.ContainerCredentialsRelativePath), func(options *endpointcreds.Options) {
            options.AuthorizationToken = envConfig.ContainerAuthorizationToken
            options.HTTPClient = &http.Client{
                Timeout: 1,
            }
        })
    default:
        provider = ec2rolecreds.New()
    }

    cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-west-2"),
        config.WithCredentialsProvider(aws.NewCredentialsCache(provider)))
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }
    r, cerr := cfg.Credentials.Retrieve(context.TODO())
    fmt.Printf("%#v\nError: %#v", r, cerr)
}

Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我明确设置了通常由默认配置读取的 AWS 环境凭证,但由于我们提供了自己的凭证提供程序,因此它们会被忽略。

// we get no valid credentials since I am neither on Ec2 or ECS
aws.Credentials{AccessKeyID:"", SecretAccessKey:"", SessionToken:"", Source:"", CanExpire:false, Expires:time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)}
Error:&fmt.wrapError{msg:"failed to refresh cached credentials, no EC2 IMDS role found, operation error ec2imds: GetMetadata, request canceled, context deadline exceeded", err:(*fmt.wrapError)(0x140000a2240)}
Run Code Online (Sandbox Code Playgroud)