-
Notifications
You must be signed in to change notification settings - Fork 549
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AmazonServiceException. The security token included in the request is expired (Service: AmazonChimeSDKMessaging; Status Code: 403; Error Code: ExpiredTokenException) #3648
Comments
Can you share code snippets in how you are configuring the Chime clients? Are you following the instructions to inject a custom credentials provider as shown here: https://docs.amplify.aws/gen1/android/sdk/configuration/amplify-compatibility/. By default, the clients would use AWSMobileClient which is incompatible with Amplify v2 and would actually caused wiped credentials. |
Hey @tylerjroach, thanks for your prompt reply. Here's how the messaging client is being configured: val CHIME_SDK_APP_INSTANCE_ARN="arn:aws:chime:us-east-1:xxxxxxxx"
lateinit var messagingClient: AmazonChimeSDKMessagingClient
lateinit var chimeUser: ChimeUser
lateinit var chimeUserCredentials: ChimeUserCredentials
/**
* The primary channel the user uses to chat with their provider.
*/
lateinit var primaryChannelArn: String
private var session: MessagingSession? = null
private var sessionMessagingId: String? = null
fun fetchSession(queryForMessages: Boolean = true) {
viewModelScope.launch {
withContext(Dispatchers.IO) {
Amplify.Auth.fetchAuthSession({
val session = it as AWSCognitoAuthSession
when (session.identityIdResult.type) {
AuthSessionResult.Type.SUCCESS -> {
val tempCreds = session.awsCredentialsResult.value as AWSTemporaryCredentials
chimeUserCredentials = ChimeUserCredentials(
accessKeyId = session.awsCredentialsResult.value!!.accessKeyId,
secretAccessKey = session.awsCredentialsResult.value!!.secretAccessKey,
sessionToken = tempCreds.sessionToken)
chimeUser = ChimeUser(
chimeDisplayName = "test",
chimeUserId = session.identityIdResult.value!!,
chimeAppInstanceUserArn = "${CHIME_SDK_APP_INSTANCE_ARN}/user/${session.userSubResult.value!!}")
initializeClient(chimeUserCredentials, chimeUser, queryForMessages)
}
AuthSessionResult.Type.FAILURE -> {
Log.w("AuthQuickStartAmplify", "IdentityId not found", session.identityIdResult.error)
}
}
},
{
Log.e("AuthQuickStartAmplify", "Failed to fetch session", it)
})
}
}
}
private fun initializeClient(credentials: ChimeUserCredentials,
chimeUser: ChimeUser,
queryForMessages: Boolean) {
messagingClient = AmazonChimeSDKMessagingClient(
BasicSessionCredentials(
credentials.accessKeyId,
credentials.secretAccessKey,
credentials.sessionToken)
).apply { setRegion(Region.getRegion("us-east-1")) }
if (queryForMessages) {
listChannelsForUser(messagingClient, chimeUser)
} else {
startMessagingSession(null)
}
}
I'm not entirely sure that I understand your comments here. I don't see a |
The recommended way to initialize the Chime clients would be to implement an The issue with the way your code is configured above is that it is taking credentials directly, and the client itself does not have the capability to refresh. When the token expires (by default, I think Cognito tokens only last 1 hour, I believe you would run into the issue you have posted. The token received in fetchAuthSession may not even be newly generated so it could even be expiring much sooner. If you pass an implementation of |
@tylerjroach Thanks again for your prompt reply.
Is this noted anywhere in the Chime documentation? Previous to your reply I had not read anything about a class AmplifyCredentialsProvider : AWSCredentialsProvider {
override fun getCredentials(): AWSCredentials = runBlocking {
suspendCoroutine { continuation ->
Amplify.Auth.fetchAuthSession(
{ authSession ->
val awsTemporaryCredentials = (authSession as? AWSCognitoAuthSession)
?.awsCredentialsResult?.value as? AWSTemporaryCredentials
val sdkCredentials = awsTemporaryCredentials?.let {
BasicSessionCredentials(it.accessKeyId, it.secretAccessKey, it.sessionToken)
}
if (sdkCredentials != null) {
continuation.resume(sdkCredentials)
} else {
val authException = RuntimeException("Failed to get credentials")
continuation.resumeWithException(authException)
}
},
{
continuation.resumeWithException(
RuntimeException("Failed to get credentials. See exception.", it)
)
}
)
}
}
override fun refresh() = runBlocking {
suspendCoroutine { continuation ->
Amplify.Auth.fetchAuthSession(
AuthFetchSessionOptions.builder().forceRefresh(true).build(),
// We do not need to capture value if refresh succeeds
{ continuation.resume(Unit) },
// We do not need to throw if refresh fails
{ continuation.resume(Unit) }
)
}
}
} Then, replacing the following: // Replaced this:
// messagingClient = AmazonChimeSDKMessagingClient(
// BasicSessionCredentials(
// credentials.accessKeyId,
// credentials.secretAccessKey,
// credentials.sessionToken)
// )
// With this:
messagingClient = AmazonChimeSDKMessagingClient(AmplifyCredentialsProvider())
.apply { setRegion(Region.getRegion("us-east-1")) } That change seems to break the integration entirely. Breakpoints in the
The original implementation I posted was called in a Fragment's ViewModel whenever the Fragment was created. I'm not sure what you meant regarding As an aside, I'd like to reiterate that this issue only just recently started occurring (~10 days ago). The implementation I originally posted has been successfully used in production for months. If the issue was an implementation issue, why did this just suddenly start occurring? Could this have been caused by configuration changes upstream, or something of the like? |
They would not be immediately expiring, but credentials from Then 30 minutes from now (either through another You can actually force
What happens when you make a call from within the client. You wouldn't expect to see credentials fetched until a method from within the client is called. What happens when you call one? Do you get an error message? Can you show the code for I'm not sure why it would begin having issues all of a sudden. If continued issues persist, it may be necessary to reach out to the Chime service team, as my team is only responsible for the SDK (which in this case has not changed). I'm just trying to rule out any configuration issues, and noticed the potential that tokens could expire (which would line up with the 403 code). |
Interesting! I was under the impression they were refreshed automatically.
That is what I expected, but you're right, it appears the credentials call is not invoked on client instantiation, but rather when some of functionality needs it (e.g. loading messages).
I'm not familiar with how long lived those tokens are expected to be. This issue started occurring in late November, about a month (and a day or two), after our initial public release. Is it possible the original tokens had a one month validity period, and are just now starting to expire? I will look into contacting Chime support; I assume that is done via an AWS Support account as per this link, but please let me know otherwise. I've refactored our code replacing That example app has not been updated in some time, so I assume it may be severely outdated and not in line with some of the other Chime documentation. Please let me know if I should be looking elsewhere! |
As an aside:
Would adding that option to the |
It looks like there may be a newer Android Chime SDK here: https://github.com/aws/amazon-chime-sdk-android. It may be worth exploring that.
The token will be refreshed automatically. This happen on a call to fetchAuthSession where we detect the token is expired (or close to expiration). You can just pass the forceRefresh flag to force it.
You can check access token validity length in the Cognito console. As far as the sample app goes, our team maintains Amplify and the AWS Android SDK. The Chime team would own the sample apps. I would recommend reaching out via the link you provided, as well as requesting that the sample app be updated to Amplify v2 as Amplify v1 is in maintenance mode and no longer supported. You may want to create a GH issue here: https://github.com/aws-samples/amazon-chime-sdk/tree/main/apps/chat-android |
Describe the bug
We've suddenly begun receiving error reports via our error reporting software that many users are encountering the following exception when attempting to send a message via Chime:
This issue appeared suddenly about a week ago across multiple app versions in the wild and doesn't seem to be associated with any application changes we've made (recent changes have been completely unrelated to anything using AWS/Chime/Cognito/Amplify). The number of occurrences seems to be rising quickly. The exception appears to occur when users are hitting the send button in our app, which sends a message via Chime's
SendChannelMessageRequest
.I have not found any relevant information regarding this error online, either related to what it signifies, why it began, or how to resolve it.
To Reproduce
We're unsure of the cause, or how to reproduce the issue. The issue seems to be occurring when a user attempts to send a message (i.e. sending a
SendChannelMessageRequest
viamessagingClient.sendChannelMessage(request)
)Which AWS service(s) are affected?
We are using AWS Chime, Cognito, and Amplify, via the following dependencies:
Expected behavior
We're expecting no exception to occur.
Screenshots
Not applicable.
Environment Information (please complete the following information):
Device: Seen on multiple device models, e.g. Samsung Galaxy S22, Pixel 6a, etc.
Android Version: Seen on multiple versions, Android 9, Android 13, Android 14
Specific to simulators: No
Additional context
Again, this issue appears to have begun occurring suddenly, and without any changes introduced by us. User's using older versions of our Android application also seem to have begun encountered the issue about a week ago, lending credit to the theory that this doesn't seem to be associated with any recent changes we've made to our application.
The text was updated successfully, but these errors were encountered: