繁体   English   中英

SQS ExpiredToken:请求中包含的安全令牌是过期状态代码:403

[英]SQS ExpiredToken: The security token included in the request is expired status code: 403

我有一个在EC2上运行的长时间运行的工作进程,它使用来自SQS队列的项目。 过了一段时间(8-12小时,我估计)我开始得到过期的安全令牌错误。 我希望aws lib能够自动处理凭证刷新,但似乎并非如此。 无论如何在客户端内处理? 仅当我使用DefaultCredentialsProviderChain生成访问时才会发生这种情况。 与密钥和密钥一起使用时不会发生此错误。 堆栈跟踪如下:

com.amazonaws.AmazonServiceException: The security token included in the request is expired (Service: AmazonSQS; Status Code: 403; Error Code: ExpiredToken; Request ID: 6ff6e1a0-d668-5ac5-bcd7-ae30058f25c0)
    at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1182)
    at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:770)
    at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:489)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:310)
    at com.amazonaws.services.sqs.AmazonSQSClient.invoke(AmazonSQSClient.java:2419)
    at com.amazonaws.services.sqs.AmazonSQSClient.receiveMessage(AmazonSQSClient.java:1130)
    at com.amazonaws.services.sqs.AmazonSQSAsyncClient$24.call(AmazonSQSAsyncClient.java:1783)
    at com.amazonaws.services.sqs.AmazonSQSAsyncClient$24.call(AmazonSQSAsyncClient.java:1779)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

我发现的解决方法是每次遇到过期令牌错误时更新awsCredentials并重置sqs客户端。

awsCredentials = (new DefaultAWSCredentialsProviderChain).getCredentials
sqs = SimpleSQSClient(awsCredentials, Regions.US_EAST_1)
queueSQS = sqs.simple(QueueName(queueName), true)

注意:我使用的是包装kifi / franz

AWS开发工具包确实能够循环从实例配置文件继承的临时凭证 ,但是通过在SimpleSQSClient的构造函数中传递显式的AWSCredentials对象,我相信您拒绝这样做的机会。

您没有明确声明您的应用程序是继承实例角色,但是您的帖子中有足够的证据可以推断出这种情况:

  • 您的应用程序在EC2上运行。
  • DefaultAWSCredentialsProviderChain的行为是查找“通过Amazon EC2元数据服务提供的实例配置文件凭据”,如果它找不到其他凭据。
  • 在未明确传递您自己的已知访问/密钥时,您只会看到此行为。

文档中描述了自动凭据刷新的特定行为:

仅当您使用默认客户端构造函数(它将自己的InstanceProfileCredentialsProvider创建为默认提供程序链的一部分)时,或者将InstanceProfileCredentialsProvider实例直接传递给客户端构造函数时,才会自动刷新凭据。 如果使用其他方法获取或传递实例配置文件凭据,则您负责检查和刷新过期的凭据。

通过直接传递AWSCredentials而不是AWSCredentialsProvider,您将负责检查和刷新过期的凭据。 从好的方面来说,如果您想要明确地传递凭据,那么您的解决方法就可以了。

SimpleSQSClient有一个构造函数,可以更好地适用于您的用例:

new SimpleSQSClient(
    credentialProvider: com.amazonaws.auth.AWSCredentialsProvider,
    region: com.amazonaws.regions.Regions,
    buffered: Boolean
)

例:

SimpleSQSClient sqs = SimpleSQSClient(new DefaultAWSCredentialsProviderChain(), Regions.US_EAST_1, false)

示例,显式使用InstanceProfileCredentialsProvider

SimpleSQSClient sqs = SimpleSQSClient(new InstanceProfileCredentialsProvider(), Regions.US_EAST_1, false)

进一步阅读:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM