aws / aws-sdk-java-v2

The official AWS SDK for Java - Version 2
Apache License 2.0
2.19k stars 845 forks source link

ExpiredTokenException is coded to 400 and not 403 and wrong error code #1649

Closed jessecoyle closed 4 years ago

jessecoyle commented 4 years ago

When DefaultStsClient decodes ExpiredTokenException it incorrectly creates a generic StsException rather than the more specific exception class.

Expected Behavior

Caused by: software.amazon.awssdk.services.sts.model.ExpiredTokenException: The security token included in the request is expired (Service: Sts, Status Code: 403, Request ID: 69d599e0-7b94-4cf4-a564-fc698225471f)

Current Behavior

Caused by: software.amazon.awssdk.services.sts.model.StsException: The security token included in the request is expired (Service: Sts, Status Code: 403, Request ID: 69d599e0-7b94-4cf4-a564-fc698225471f)

Possible Solution

In the following lines in DefaultStsClient.java

.registerModeledException(
                        ExceptionMetadata.builder().errorCode("ExpiredTokenException")
                                .exceptionBuilderSupplier(ExpiredTokenException::builder).httpStatusCode(400).build())

change 400 to 403, unless there are cases where it might also come through as a 400? change "ExpiredTokenException" to "ExpiredToken"

Steps to Reproduce (for bugs)

This is a bit tricky to reproduce naturally.

Context

Expected exception catching failed, and a generally recoverable situation turned into a non recoverable error.

Your Environment

debora-ito commented 4 years ago

Hi @jessecoyle, the SDK auto generates the clients from models provided by the service teams, and the models also define which exceptions you get for each operation - https://github.com/aws/aws-sdk-java-v2/blob/2.10.41/services/sts/src/main/resources/codegen-resources/service-2.json

If the call results in an exception not in the model, the SDK returns the generic StsException exception.

Based on the STS model, you should see ExpiredTokenException when calling AssumeRoleWithSAML and AssumeRoleWithWebIdentity operations.

If it's not what you are experiencing, please provide a code sample we can use to reproduce the issue.

jessecoyle commented 4 years ago

I believe the error is on this line and the following

https://github.com/aws/aws-sdk-java-v2/blob/2.10.41/services/sts/src/main/resources/codegen-resources/service-2.json#L436

It incorrectly lists the code as ExpiredTokenException, when that is the exception name, the actual code is ExpiredToken. It also lists the wrong http status.

Unfortunately I can't find this error code listed on the API reference at https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html or at https://docs.aws.amazon.com/STS/latest/APIReference/CommonErrors.html

Reproducing this error requires a valid but very old token and is hard to reproduce in a single code example. I can do this by faking responses from AWS but I'm guessing that would be unsatisfying.

debora-ito commented 4 years ago

I ran a quick test and called STS AssumeRole with expired credentials, and here's the exception I got:

Exception in thread "main" com.amazonaws.services.securitytoken.model.AWSSecurityTokenServiceException: The security token included in the request is expired (Service: AWSSecurityTokenService; Status Code: 403; Error Code: ExpiredToken; Request ID: xxx)

So this ExpiredToken is actually a different error code from the ExpiredTokenException you linked, which is used for web identity token validations according to its description.

I'll reach out to the STS team and ask them to add the ExpiredToken to the service model in the AssumeRole operation. Will let you know when we hear back.

jessecoyle commented 4 years ago

Thank you, that appears correct. Keep in mind the difference in the Status Code is also important. The real code is 403, but the code in the model is 400

debora-ito commented 4 years ago

Hi @jessecoyle the STS team acknowledged this. I'll go ahead and close this, as the issue is now in the service team backlog.

Feel free to reach out if you have other questions.