请求中包含的安全令牌已过期

The security token included in the request is expired

我有一个脚本可以从 Cloudwatch 中提取大量指标用于我们自己的内部报告。

该脚本迭代特定区域中的所有 EC2 实例,并请求过去 2 周的 5 个 cloudwatch 指标(所有可用的统计数据)(每次 5 天以 5 分钟为间隔,正好是 1440 配额) ).我正在使用假定的会话:

session = Session(aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY, region_name=regionName)
sts = session.client('sts')
response = sts.assume_role(
    RoleArn=arn, # External role arn
    RoleSessionName='role-name',
    ExternalId='<some-id-here>',
)
tempAccessKeyId = response['Credentials']['AccessKeyId']
tempSecretAccessKey = response['Credentials']['SecretAccessKey']
tempSessionToken = response['Credentials']['SessionToken']
assumedSession = Session(
    aws_access_key_id=tempAccessKeyId,
    aws_secret_access_key=tempSecretAccessKey,
    aws_session_token=tempSessionToken,
    region_name=regionName)

虽然 运行 我得到这个异常的脚本:

botocore.exceptions.ClientError: An error occurred (ExpiredToken) when calling the GetMetricStatistics operation: The security token included in the request is expired

有没有办法确保令牌在 运行 脚本期间不会过期?我正在使用 boto3。

您正在使用的 assume_role 方法 returns 临时 安全凭证。以下摘自official documentation:

The temporary security credentials are valid for the duration that you specified when calling AssumeRole , which can be from 900 seconds (15 minutes) to 3600 seconds (1 hour). The default is 1 hour.

由于您没有使用 DurationSeconds 关键字参数,因此返回的凭据在默认 1 小时内有效。您必须确保获得新凭据才能在 1 小时后发出请求。请参阅 Temporary Security Credentials official documentation 中的以下内容:

When (or even before) the temporary security credentials expire, the user can request new credentials, as long as the user requesting them still has permissions to do so.

我发现 AWS Premium Support answer 这个问题非常简洁和相关

同样重要的是要注意当服务器时间偏离正确时间时有时会出现错误(10-15 分钟会导致错误)

我也遇到这个错误,甚至我检查了我的 .aws/credential 文件。它包含凭据,但我仍然建议执行以下步骤:

在做任何事情之前,首先你必须按照命令运行

aws sts get-caller-identity

如果您在 aws credential 中有多个配置文件,请使用这个

您可以在以下文件 .aws/credential 中查看您的个人资料。如果你只有 [default] 那么就不需要提到个人资料

aws --profile NAME_OF_YOUR_PROFILE  sts get-caller-identity

现在的问题是上面的命令能解决问题吗?

不,但至少它会让您知道您的凭据是否正确。我遇到了同样的错误,当我 运行 以上命令时,它给了我以下错误

An error occurred (SignatureDoesNotMatch) when calling the GetCallerIdentity operation: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.

所以至少我发现我使用了错误的凭据。我只是更换了凭据,我的问题就解决了。

在我的情况下,问题是,我的 .aws/configure 中有凭据,并试图从中进行配置,但我没有意识到我还有另一对凭据 AWS_SESSION_TOKEN AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY 设置环境变量.

您可以这样做(这将从环境中删除凭据)。

unset AWS_SESSION_TOKEN AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY

现在您将只有一组访问密钥,即在 .aws/configure 中,我能够成功建立连接。

aws configure
aws sts get-caller-identity

如果您使用的不是默认配置文件,请在上述命令中使用 --profile 标志。

实例时间同步问题也可能导致阻止 IAM 令牌刷新,我尝试了所有解决方案但没有任何效果,最后发现它与实例和 AWS 服务的时间差异。安装 chrony 可以帮助实现自动时间同步。