在 Amazon EC2 上运行 Java 应用程序时,如何解决“请求中包含的安全令牌已过期”错误?

上次更新时间:2020 年 8 月 27 日

在 Amazon Elastic Compute Cloud (Amazon EC2) 实例上运行的 Java 应用程序(使用适用于 Java 的 AWS 开发工具包)可能会遇到类似以下内容的异常:

com.amazonaws.AmazonServiceException: The security token included in the request is expired (Service: AmazonSQS; Status Code: 403; Error Code: ExpiredToken; Request ID: 12a345b6-78cd-901e-fg23-45hi67890jkl)

简短描述

必须使用 AWS 颁发的凭证对发送到 Amazon Web Services (AWS) 的所有应用程序 API 请求进行加密签名。

如果您的应用程序在创建 AWS 客户端时使用了临时凭证,则凭证在创建时指定的时间间隔后过期。您必须在凭证过期之前刷新凭证。

另一个过期原因是使用的时间不正确。对于许多服务器任务和进程来说,准确一致的时间参考非常重要。如果实例的日期和时间设置不正确,则 AWS 凭证会被拒绝。

如果您的应用程序运行在 Amazon EC2 实例上,最佳做法是使用分配给此实例的 AWS Identity and Access Management (IAM) 角色。使用 IAM 角色将允许使用默认服务构造函数。默认构造函数客户端按以下顺序使用默认凭证提供程序链搜索凭证:

  1. 系统环境变量:AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY
  2. Java 系统属性:aws.accessKeyIdaws.secretKey
  3. 默认凭证文件(在不同平台上该文件位于不同位置)。
  4. 实例配置文件凭证:包含在与 EC2 实例的 IAM 角色关联的实例元数据中。通过将实例配置文件附加到您的实例,可将实例配置文件凭证添加到默认凭证提供程序链。有关更多信息,请参阅使用 IAM 角色向在 Amazon EC2 实例上运行的应用程序授予权限
    如果实例配置文件凭证可用,默认客户端构造函数会创建 AWS 开发工具包 InstanceProfileCredentialsProvider 类的一个实例。AWS 使用此类来通过 AWS 凭证签署 API 请求,使用的是来自 Amazon EC2 实例元数据临时安全凭证

重要提示:如果您的应用程序使用 AWS 开发工具包 ProfileCredentialsProvider 类提供临时 AWS 凭证,则由您负责检查凭证并在过期前进行刷新。不检查或不刷新凭证可能会增加 ExpiredToken 错误引发应用程序故障的可能性。

解决方法

使用 Amazon Time Sync Service 或 NTP 源

要确保您的 Linux 实例包含一致、准确的时间参考,请在您的 Amazon EC2 实例上配置 Amazon Time Sync Service 或其他网络时间协议 (NTP) 源。有关更多信息,请参阅为 Linux 实例设置时间为 Windows 实例设置时间

使用自定义临时 AWS 凭证

在临时凭证过期之前的 5 分钟刷新这些凭证。

使用分配给实例的 IAM 角色

为您的实例附加一个实例配置文件。有关更多信息,请参阅使用 IAM 角色向在 Amazon EC2 实例上运行的应用程序授予权限。验证未在您的代码或实例中指定其他凭证。实例配置文件凭证是默认凭证提供程序链搜索凭证的最后一个位置。如果您将凭证放置在搜索链中靠前的任何位置,则这些凭证将阻止使用 IAM。有关更多信息,请参阅使用 AWS 凭证

要查看附加到实例的 IAM 角色的 AWS 凭证,请在 Linux shell 或 Windows PowerShell(v3.0 或更高版本)中运行以下命令。请务必将 examplerole 替换为您的 IAM 角色的名称。

对于 Linux,请使用 curl 命令查看 AWS 凭证:

$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/examplerole

此命令会返回类似以下内容的输出:

{
    "Code" : "Success",
    "LastUpdated" : "2016-04-26T16:39:16Z",
    "Type" : "AWS-HMAC",
    "AccessKeyId" : "AKIAIOSFODNN7EXAMPLE",
    "SecretAccessKey" : "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
    "Token" : "token",
    "Expiration" : "2016-04-27T22:39:16Z"
}

对于 Windows,请使用 Invoke-RestMethod 命令查看 AWS 凭证:

PS C:\> Invoke-RestMethod http://169.254.169.254/latest/meta-data/iam/security-credentials/examplerole

此命令会返回类似以下内容的输出:

Code            : Success
LastUpdated     : 2016-07-18T18:09:47Z
Type            : AWS-HMAC
AccessKeyId     : AKIAIOSFODNN7EXAMPLE
SecretAccessKey : wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Token           : token
Expiration      : 2016-04-27T22:39:16Z

使用上述命令检查实例的最新临时凭证。这些凭证在分配的临时凭证过期前约 5 分钟自动轮换或刷新。


使用 AWS 凭证(适用于 Java 的 AWS 开发工具包)

提供和检索 AWS 凭证(适用于 Java 2.0 的 AWS 开发工具包)

适用于 Amazon EC2 的 IAM 角色

为 Amazon EC2 配置 IAM 角色(高级)

这篇文章对您有帮助吗?


您是否需要账单或技术支持?