加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-15 04:33:53 所属栏目:Java 来源:网络整理
导读:我有一个在EC2上运行的长时间运行的工作进程,它使用来自SQS队列的项目.过了一段时间(8-12小时,我估计)我开始得到过期的安全令牌错误.我希望aws lib能够自动处理凭证刷新,但似乎并非如此.无论如何在客户端内处理? 仅当我使用DefaultCredentialsProviderChain
我有一个在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元数据服务提供的实例配置文件凭据”,如果它找不到其他凭据.
>当您没有显式传递您自己的已知访问/密钥时,您才会看到此行为.

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

The automatic credentials refresh happens only when you use the
default client constructor,which creates its own
InstanceProfileCredentialsProvider as part of the default provider
chain,or when you pass an InstanceProfileCredentialsProvider instance
directly to the client constructor. If you use another method to
obtain or pass instance profile credentials,you are responsible for
checking for and refreshing expired credentials.

通过直接传递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(),false)

进一步阅读:

> AWS SDK for Java > DefaultAWSCredentialsProviderChain – 更详细地描述默认提供商链
> kini/franz – Initialization – SimpleSQSClient构造函数参考
> AWS SDK for Java >
Developer Guide > Using IAM Roles to Grant Access to AWS Resources on Amazon EC2 – 正确使用临时凭证的绝佳资源
>更新2017/11/06:在AWS SDK for Java 2.0预览期间,DefaultAWSCredentialsProviderChain已重命名为DefaultCredentialsProvider.预览文档here.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读