在 Amazon Elastic Compute Cloud (Amazon EC2) 实例上使用适用于 Java 的 AWS SDK 的 Java 应用程序收到以下错误:“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 要求使用 AWS 提供的凭证对所有应用程序 API 请求进行数字签名。当应用程序使用临时凭证创建 AWS 客户端时,必须在凭证过期之前续订这些凭证。如果您的凭证过期,您将会收到 security token included in the request is expired(请求中包含的安全令牌已过期)错误。要解决此错误,请检查您的时间参考,刷新过期的临时凭证,然后检查您的 AWS Identity and Access Management (IAM) 配置。
解决方法
确保您的实例具有一致的时间参考
如果凭证使用的时间不正确,则会导致凭证过期,因此请确保您的服务器准确无误。您的 EC2 实例必须具有一致且准确的时间和日期参考。在您的实例上配置 Amazon Time Sync Service 或其他网络时间协议 (NTP) 源。有关详细信息,请参阅更改实例的时区。
确保您的临时凭证未过期
如果您使用临时凭证,请确保它们没有过期。如果临时凭证已过期,则您必须生成一组新的临时凭证并使用这些凭证。最佳做法是在临时凭证过期前五分钟刷新该凭证。
检查您的 IAM 配置
对于在 EC2 实例上运行的应用程序,最佳做法是使用分配给该实例的 IAM 角色。如果您使用 IAM 角色,请检查您的配置是否设置正确。
使用 IAM 角色时,默认服务构造函数将使用默认凭证提供商链按以下顺序搜索凭证:
- 系统环境变量 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY。
- Java 系统属性 aws.accessKeyId 和 aws.secretKey。
- 默认凭证文件。
- 实例配置文件凭证,位于与 IAM 角色关联的实例元数据中。
有关详细信息,请参阅使用 IAM 角色向在 Amazon EC2 实例上运行的应用程序授予权限。
如果您列出除实例配置文件以外的任何位置的凭证,则默认客户端构造函数会首先找到这些凭证。此配置会阻止 IAM 角色凭证。有关详细信息,请参阅为适用于 Java 的 AWS SDK 提供临时凭证。
要查看 IAM 角色的凭证,请在 Windows PowerShell 3.0 或更高版本中或 Linux Shell 中运行以下命令。如果您使用临时凭证,则以下 Windows 和 Linux 命令会显示实例的最新临时凭证。
**注意:**在以下命令中,请将 examplerole 替换为您的 IAM 角色的名称。
Windows:
PS C:\> Invoke-RestMethod http://169.254.169.254/latest/meta-data/iam/security-credentials/examplerole
您收到的输出结果类似于以下示例:
Code : SuccessLastUpdated : 2016-07-18T18:09:47Z
Type : AWS-HMAC
AccessKeyId : AKIAIOSFODNN7EXAMPLE
SecretAccessKey : wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Token : token
Expiration : 2016-04-27T22:39:16Z
Linux:
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"
}
如果您在运行前面的 curl 命令时收到 404 错误,请验证是否为元数据 IP 地址关闭了 HTTP 代理。此外,请确保实例配置文件已附加到实例。
如果问题仍然存在,请确认该实例没有发出多个并发请求或并行运行多个会话。这种情况可能会导致实例元数据服务 (IMDS) 限制查询。要缓解此问题,请使用通过指数回退重试模式。
要设置重试,请修改 AWS_METADATA_SERVICE_NUM_ATTEMPTS。要设置选项,请使用环境变量、~/.aws/config 文件或用户的 botocore 会话。有关详细信息,请参阅 Boto3 文档网站上的配置。
示例:
AWS_METADATA_SERVICE_TIMEOUT = 10
AWS_METADATA_SERVICE_NUM_ATTEMPTS = 5
如果您在 Docker 容器中运行 curl 命令,请将 http-put-response-hop-limit 增加到 2。运行以下 AWS 命令行界面 (AWS CLI) 命令 modify-instance-metadata-options:
aws ec2 modify-instance-metadata-options --instance-id instance --http-put-response-hop-limit 2 --http-endpoint enabled
**注意:**请将 instance 替换为您的实例 ID。如果您在运行 AWS CLI 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,确保您使用的是最新版本的 AWS CLI。
有关详细信息,请参阅 Add defense in depth against open firewalls, reverse proxies, and SSRF vulnerabilities with enhancements to the EC2 Instance Metadata Service。
角色凭证会在分配的临时凭证过期前五分钟自动轮换或刷新。
相关信息
配置 SDK 身份验证
适用于 Amazon EC2 的 IAM 角色