登录
首页 >  Golang >  Go问答

使用 Node.js 的 aws-sdk 包成功获取 AWS STS AssumeRole 的临时凭证,但使用 Golang 的 aws-sdk 获取相同凭证和角色 ARN 失败

来源:stackoverflow

时间:2024-02-06 08:21:25 376浏览 收藏

来到golang学习网的大家,相信都是编程学习爱好者,希望在这里学习Golang相关编程知识。下面本篇文章就来带大家聊聊《使用 Node.js 的 aws-sdk 包成功获取 AWS STS AssumeRole 的临时凭证,但使用 Golang 的 aws-sdk 获取相同凭证和角色 ARN 失败》,介绍一下,希望对大家的知识积累有所帮助,助力实战开发!

问题内容

我有 golang 和 nodejs 代码来获取同一组凭据 accesskey、secretkey 和 rolearn 的临时凭据。 nodejs 代码给了我临时信用,而 go 代码给了我以下错误

操作错误 sts:assumerole,https 响应错误 statuscode:403,requestid:ebccfbf8-abed-4490-83ce-730d87d131,api 错误 accessdenied:用户:arn:aws:iam:::user/sts-user-1234无权对资源执行:sts:assumerole:arn:aws:iam:::role/sts-role-123 有人可以帮我解决这个问题吗?

下面是我的 go 代码的链接。

https://go.dev/play/p/txv2cttsitd

使用的软件包版本:

github.com/aws/aws-sdk-go-v2 v1.20.0 github.com/aws/aws-sdk-go-v2/config v1.18.29 github.com/aws/aws-sdk-go-v2 /service/sts v1.20.0

package main

import (
    "context"
    "errors"
    "fmt"
    "net/http"
    "os"

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

// awsprovider ...
type awsprovider struct{}

// newawsprovider ...
// var newawsprovider connection = &awsprovider{}

var (
    defaultregion      = "us-east-1"
    defaultsessionname = "mcmp"
)

// connectionvalidation ...
type connectionvalidation struct {
    connectionid  string   `json:"connectionid" bson:"connectionid"`
    vaultconfigid string   `json:"vaultconfigid,omitempty"`
    provider      provider `json:"provider,omitempty" bson:"provider"`
    reference     string   `json:"reference,omitempty" bson:"reference"`
}

type provider struct {
    type        string                 `json:"type" bson:"type" validate:"required"`
    configdata  map[string]interface{} `json:"configdata,omitempty" bson:"configdata,omitempty"`
    credentials []fields               `json:"credentials,omitempty" bson:"credentials,omitempty"`
}

type fields struct {
    key   string `json:"key"`
    value string `json:"value"`
}

// validate ...
func validate(connection *connectionvalidation) (err error) {
    accesskey := ""
    secretkey := ""

    configdata := connection.provider.configdata
    if configdata["delegatedaccess"] != nil {
        delegatedaccess, ok := configdata["delegatedaccess"].(string)
        if !ok || delegatedaccess == "" {
            err = errors.new("invalid delegatedaccess")
            return
        }
        err = validatedelegatedaccess(connection, accesskey, secretkey, delegatedaccess)
        return
    }

    err = validateasset(accesskey, secretkey, defaultregion)
    return
}

// checkandaddproxy ...
func checkandaddproxy(config aws.config) aws.config {
    if os.getenv("https_proxy") != "" {
        httpclient := &http.client{
            transport: &http.transport{
                proxy: http.proxyfromenvironment,
            },
        }
        config.httpclient = httpclient
    }
    return config
}

func validatedelegatedaccess(connection *connectionvalidation, accesskey, secretkey, delegatedaccess string) (err error) {
    config, err := config.loaddefaultconfig(context.todo(), config.withregion(defaultregion))
    if err != nil {
        panic("configuration error validatedelegatedaccess, " + err.error())
    }
    config = checkandaddproxy(config)
    config.region = defaultregion

    config.credentials = aws.newcredentialscache(credentials.newstaticcredentialsprovider(accesskey, secretkey, ""))

    client := sts.newfromconfig(config)

    params := &sts.assumeroleinput{
        rolearn:         &delegatedaccess,
        rolesessionname: &defaultsessionname,
    }

    configdata := connection.provider.configdata
    if configdata["externalid"] != nil {
        externalid, ok := configdata["externalid"].(string)
        if !ok || externalid == "" {
            err = errors.new("invalid externalid")
            return
        }
        params.externalid = &externalid
    }

    _, err = client.assumerole(context.todo(), params)
    return
}

func validateasset(accesskey, secretkey, region string) (err error) {
    config := *aws.newconfig()
    config.region = defaultregion
    config.credentials = aws.newcredentialscache(credentials.newstaticcredentialsprovider(accesskey, secretkey, ""))
    config = checkandaddproxy(config)

    client := sts.newfromconfig(config)

    input := &sts.getcalleridentityinput{}
    _, err = client.getcalleridentity(context.todo(), input)
    if err != nil {
        return err
    }
    return
}

func main() {
    fmt.println("---validate aws creds---")
    conn := connectionvalidation{
        connectionid: "id",
        provider: provider{type: "aws",
            configdata: map[string]interface{}{"accountnumber": "",
                "delegatedaccess": "",
                "externalid":      "12345"},
        },
    }
    err := validate(&conn)
    if err != nil {
        fmt.printf("\n --- error validate aws creds---%+v", err)
    } else {
        fmt.println("validate creds success")
    }

}

这是 nodejs 代码

软件包版本: "aws-sdk": "^2.1429.0"

var AWSClient = require('aws-sdk');
var proxy = require('proxy-agent');

var checkForProxy = function () {
  if (process.env.https_proxy !== undefined) {
    console.log("Configuring AWS client to use https proxy");
    AWSClient.config.update({
      httpOptions: { agent: proxy(process.env.https_proxy) }
    });
  }
}

async function getTempCredentials(result) {
  console.log('-- Inside credential-validator-service/getTempCredentials... --');
  try {
    return new Promise(function (resolve, reject) {
      if (result['delegatedAccess'] && result['accessKey'] && result['secretKey']) {
        AWSClient.config.update({
          accessKeyId: result['accessKey'],
          secretAccessKey: result['secretKey'],
          region:"us-east-1"
        });
        checkForProxy()
        console.log("AWSClient config-----")
        console.log(AWSClient.config)
        var sts = new AWSClient.STS();
        var params = {
          RoleArn: result['delegatedAccess'],
          RoleSessionName: "MCMP"
        };
        if (result['externalId']) {
          console.log("Found externalId in payload, validating ARN with externalId")
          params['ExternalId'] = result['externalId']
        }
        sts.assumeRole(params, function (err, result) {
          if (err) {
            console.log("Error occured " + JSON.stringify(err));
            reject(err);
          } else {
            console.log("Temporary credential retrieved successfully");
            resolve({
              "message": "Delegated Credentials fetched successfully",
              "delegatedcredentials": result['Credentials'],
              "translateCode": "CO200_FETCH_SUCCESS",
              "translateParameters": [],
              "statusCode": 200
            });
          }
        });
      } else {
        reject({
          "message": "Required credential details not found to fetch role, please provide arn, accessKey and secretKey",
          "translateCode": "CO400_FETCH_FAIL",
          "translateParameters": [],
          "statusCode": 400
        });
      }
    });
  } catch (error) {
    console.log.error("error while calling assume role of aws : " + JSON.stringify(error));
    return {
      "message": "System Failure. Due to: " + error.message,
      "translateCode": "CO500_ERR",
      "translateParameters": [error.message],
      "statusCode": 500
    }
  }
}

const checkDelegateAndUpdate = (body, callback) => {
  if (body.credentials.delegatedAccess) {
    const payload = {
      accessKey: body.credentials.passwordFields.accessKey,
      secretKey: body.credentials.passwordFields.secretKey,
      delegatedAccess: body.credentials.delegatedAccess,
      externalId: body.credentials.externalId
    };
    getTempCredentials(payload).then(({
      delegatedcredentials
    }) => {
      AWSClient.config.update({
        accessKeyId: delegatedcredentials.AccessKeyId,
        secretAccessKey: delegatedcredentials.SecretAccessKey,
        sessionToken: delegatedcredentials.SessionToken
      });
      callback(null, "Success");
    }).catch(err => {
      console.log("Error occured while fetching temporary credentials ", err.message);
      callback(err);
    });
  } else {
    AWSClient.config.update({
      accessKeyId: body.credentials.passwordFields.accessKey,
      secretAccessKey: body.credentials.passwordFields.secretKey
    });
    callback(null, "Success");
  }
}

var testAccount = function (asset_payload, callback) {

  if (!asset_payload.credentials.passwordFields.accessKey ||
    !asset_payload.credentials.passwordFields.secretKey) {
    return callback(Error, null);
  } else {
    checkDelegateAndUpdate(asset_payload, (err, _res) => {
      if (err) {
        return callback(err, null);
      } else {
        AWSClient.config.update({
          accessKeyId: asset_payload.credentials.passwordFields.accessKey,
          secretAccessKey: asset_payload.credentials.passwordFields.secretKey
        });

        checkForProxy()
        var sts = new AWSClient.STS();
        sts.getCallerIdentity({}, function (err, response) {
          if (err) {
            return callback(err, null);
          } else {
            return callback(null, response);
          }
        });
      }
    });
  }
};

var requestPayload = {
    "basicInfo": {
        "accountName": "camaws",
        "serviceProviderType": "aws",
        "serviceProviderCode": "aws",
        "isActive": "Active",
        "accountType": "subaccount",
        "userType": "asset"
    },
    "advancedInfo": {
        "accountNumber": ""
    },
    "credentials": {
        "credentialName": "awscred",
        "purpose": ["assetIngestion"],
        "status": true,
        "externalId": "12345",
        "delegatedAccess": "",
        "passwordFields": {
            "accessKey": "",
            "secretKey": "",
            "additionalInfo": ""
        }
    }
}


testAccount(requestPayload, function (err, result) {
    if (err) {
        console.log(err)
    }else{
        console.log("success*********")
        console.log(result)
    }
});

正确答案


访问被拒绝意味着访问被拒绝。 因此,您的 IAM 策略可能不允许您担任该角色。 检查 sts 假设调用的参数。 可以在这里找到 go 承担角色的工作示例:https://www.go-on-aws.com/aws-go-sdk-v2/sts/crossaccount/ 出于安全原因,请确保永远不要将访问密钥和访问秘密直接放入代码中。

今天关于《使用 Node.js 的 aws-sdk 包成功获取 AWS STS AssumeRole 的临时凭证,但使用 Golang 的 aws-sdk 获取相同凭证和角色 ARN 失败》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>