寻找更新AWS凭证的更好方法

时间:2019-03-11 10:03:24

标签: node.js amazon-web-services amazon-s3 promise

我正在使用sts:assumeRole连接到其他帐户的s3存储桶。 现在,我运行的工作需要几天的时间,并且凭证过期,因此需要一种续订凭证的方法。

我编写了以下代码来处理临时凭证的过期

此代码在我的downloadFile()中:

return new Promise((resolve, reject) => {
    function responseCallback(error, data) {
        if (error) {
            const errorMessage = `Fail to download file from s3://${config().s3.bucket}/${path}: ${error};`;
            reject(error);
        } else {
            Logger.info(`Successfully download file from s3://${config().s3.bucket}/${path}`);
            resolve(data.Body);
        }
    }
    const fn = this.s3Client.getObject({
        Bucket: config().s3.bucket,
        Key: path
    }, (error, data) => this.handleTokenExpiry(error, data, fn, responseCallback));
});

这是handleTokenExpiry()

handleTokenExpiry(error, data, fn, callback) {
    if (!error || error.code !== "ExpiredToken") return callback(error, data);

    Logger.info("Token expired, creating new token");
    this.s3Client = null; // null so that init() doesn't return existing s3Client
    return this.init().then(fn);
}

这里init()是使用this.s3Client设置sts:assumeRole的方法 然后new AWS.S3()

这很好,但是我不确定这是否是一种干净的方法。奇怪的是,当我在本地对其进行测试时,令牌过期后将需要近两分钟的时间来调用responseCallback()。尽管responseCallback()在令牌处于活动状态时会立即执行。

2 个答案:

答案 0 :(得分:2)

对于运行时间少于12h的任务,这是解决方案。

使用AssumeRole时,可以指定DurationSeconds参数来指定STS返回的临时证书的持续时间。最少15分钟,最多12小时。

您还需要修改您假设的角色以授权最大持续时间。参见https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session

根据您的情况,一项工作要运行几天。我建议将应用重构为小批量运行,每批运行几个小时。

另一种选择是主动权衡令牌到期。如果您的代码知道令牌的持续时间和获取令牌的时间,则建议在调用使用令牌的方法(例如S3的getObject)之前先调用一个方法。您可以使用该方法检查令牌是否即将过期,并主动刷新令牌。伪代码就像

function refreshToken() {
   return new Promise( (resolve, reject) => {
      // XX depends how long is your S3 getObject call
      if (token_acquisition_time + token_duration <= now() + xx minutes)  {
         // refresh token
         sts.assumeRole(...).promise().then(resolve());
      } else {
         resolve();
      }
   });
}

...

refreshToken.then(s3.getObject(...));

答案 1 :(得分:0)

AWS开发工具包可以为您处理刷新凭证。例如:

const credentials = new ChainableTemporaryCredentials({
  params: {
    RoleArn: "optional-role-arn",
    RoleSessionName: `required-parameter-${Date.now()}`
  }
})
const s3 = new AWS.S3({credentials})

现在,AWS SDK将在后台刷新令牌,而无需s3的调用者采取任何行动。 有关更多信息,请参见AWSK SDK Documentation。刷新仅限于所用凭据的有效时间。