【问题标题】:Find a better way to renew AWS credentials寻找更新 AWS 凭证的更好方法
【发布时间】:2020-10-30 21:07:06
【问题描述】:

我正在使用 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()是使用sts:assumeRole设置this.s3Client的方法 然后new AWS.S3()

这很好用,但我不确定这是否是一种干净的方法。奇怪的是,当我在本地测试它时,在令牌过期时调用 responseCallback() 几乎需要 两分钟。虽然 responseCallback() 会在令牌处于活动状态时立即执行。

【问题讨论】:

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


    【解决方案1】:

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

    使用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(...));
    

    【讨论】:

    • 是的,我知道 DurationSeconds,我跳过了它,因为创建角色的人将最大持续时间保持为 1 小时,当您未指定此参数时,AWS 将默认值设为 1 小时反正。您的预检查到期解决方案似乎很有趣,我会尝试一下。
    【解决方案2】:

    AWS SDK 可以为您处理刷新凭证。例如:

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

    现在 AWS 开发工具包将在后台刷新令牌,而无需 s3 调用者的任何操作。 如需更多信息,请参阅AWSK SDK Documentation。刷新仅限于所用凭据的有效期。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-18
      • 1970-01-01
      • 1970-01-01
      • 2014-10-21
      • 2017-08-11
      • 2014-07-20
      • 2014-05-04
      相关资源
      最近更新 更多