NodeJS调用AWS STS AssumeRole成功,Go同凭证报403错误求助
AWS STS AssumeRole 403错误:Go代码失败但NodeJS成功
我分别用Golang和NodeJS编写代码,使用同一组accessKey、secretKey和roleARN获取AWS临时凭证。NodeJS代码能成功获取,但Go代码抛出如下权限错误:
operation error STS: AssumeRole, https response error StatusCode: 403, RequestID: ebccfbf8-abed-4490-83ce-730d87d131, api error AccessDenied: User: arn:aws:iam::<accountID>:user/sts-user-1234 is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::<accountID>:role/sts-role-123
Go代码相关
使用的包版本
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
Go代码
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 := "<accessKey>" secretKey := "<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": "<accountNumber>", "delegatedAccess": "<ARN>", "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"
NodeJS代码
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": "<accountumber>" }, "credentials": { "credentialName": "awscred", "purpose": ["assetIngestion"], "status": true, "externalId": "12345", "delegatedAccess": "<ARN>", "passwordFields": { "accessKey": "<accessKey>", "secretKey": "<secretKey>", "additionalInfo": "" } } } testAccount(requestPayload, function (err, result) { if (err) { console.log(err) }else{ console.log("success*********") console.log(result) } });
内容的提问来源于stack exchange,提问作者Neha
相关产品推荐
相关产品推荐

