1

I've spring boot app with QueueMessagingTemplate as client to access Amazon SQS using temporary security credentials(STS). Getting temp token using STS-AssumeRole . Can you help me how to refresh/auto-refresh session token when it expires?

Error: com.amazonaws.services.sqs.model.AmazonSQSException: The security token included in the request is expired

Here is the code:

@Configuration
@Slf4j
public class QueueConfig {

    @Bean
    public QueueMessagingTemplate queueMessagingTemplate(@Autowired BasicSessionCredentials sessionCredentials) {
            log.info("queueMessagingTemplate refresh");
            return new QueueMessagingTemplate(amazonSQSAsync(sessionCredentials));
    }

    @Bean
    @Primary
    public AmazonSQSAsync amazonSQSAsync(BasicSessionCredentials sessionCredentials) {
            return AmazonSQSAsyncClientBuilder
                    .standard()
                    .withRegion(Regions.US_WEST_1)
                    .withCredentials(new AWSStaticCredentialsProvider(sessionCredentials))
                    .build();
    }
}

Here is the code for AWS STS cred

@Configuration
@Slf4j
public class AwsRoleCredentials {

    @Bean(name = "sessionCredentials")
    public BasicSessionCredentials sessionCredentials(){
        try {
            String roleArn = "XXXX";
            String roleSessionName = "XXX";
            Region region = Region.US_WEST_1;

            StsClient stsClient = StsClient.builder()
                    .region(region)
                    .build();

            AssumeRoleRequest roleRequest = AssumeRoleRequest.builder()
                    .roleArn(roleArn)
                    .roleSessionName(roleSessionName)
                    .build();

            AssumeRoleResponse roleResponse = stsClient.assumeRole(roleRequest);
            Credentials myCreds = roleResponse.credentials();


            BasicSessionCredentials sessionCred = new BasicSessionCredentials(
                    myCreds.accessKeyId(),
                    myCreds.secretAccessKey(),
                    myCreds.sessionToken());
            return sessionCred;

        } catch (StsException e) {
            log.error("ERROR while get token:"+ e.getMessage());
        }
        return null;
    }
}
    
suru
  • 11
  • 1
  • 3
  • Can't you just call `AssumeRole` again? – John Rotenstein Aug 27 '21 at 21:52
  • QueueMessagingTemplate is autowired into my application queue listener class and BasicSessionCredentials are atuowired into QueueMessagingTemplate. How can I re-initialize these spring beans. – suru Aug 29 '21 at 01:42
  • My spring SQS is implemented like below except the credentials are AssumeRole (temp credentials) https://examples.javacodegeeks.com/using-amazon-sqs-with-spring-boot/. AWS SDK is supposed to recognize that the credentials have expired and refresh them, but that doesn't seem to be working. – suru Aug 29 '21 at 01:53
  • I don't think it can auto-refresh credentials that you have extracted from AssumeRole and put into `sessionCred`. It has no ability to call `AssumeRole` on its own. When using an IAM Role assigned to an EC2 instance, the credentials are auto-refreshed, but not if you assume the role in your own program. – John Rotenstein Aug 29 '21 at 02:25
  • Thank you. I will try this out. If the IAM Role assigned to an EC2 instance, BasicSessionCredentials will be auto-refreshed ? – suru Aug 30 '21 at 05:02
  • When an IAM Role is assigned to an Amazon EC2 instance, then the AWS SDK will automatically receive credentials. There is no need to process credentials unless you wish to assume different credentials. – John Rotenstein Aug 30 '21 at 05:15

1 Answers1

1

I was just about to implement it myself and then i found that in version 2 of the sdk its already there, you can use StsAssumeRoleCredentialsProvider which takes care of refreshing the token when it is about to expire. I don't know if there is something equivalent in the old SDK.

But you can implement it pretty easily for the older SDK as well, just store the expiry and make another assumeRole request when it's about to expire

Edit- I was confused because you use the v1 sdk for SQS but you do use the V2 SDK for STS, so you can simply use StsAssumeRoleCredentialsProvider instead. Also, I suggest using either V1 or V2, but not both

paranoidAndroid
  • 523
  • 5
  • 12
  • For sure this can be accepted as answer!!! Using StsAssumeRoleCredentialsProvider will auto-refresh the sts token! – Stan Jan 19 '23 at 23:04