AWS SDK Cognito Hosted UI - back button hangs rather than cancelling login
Re-opening an issue that got auto-closed and still happens with 2.53.0
Don't try and distract with irrelevant comments about Amplify, which doesn't let us set file upload permissions and has no Kinesis support (which is why the last issue got auto closed!).
This is about the Android AWS SDK
We use multiple login methods, so have a screen with AWS login and our legacy login buttons. The AWS login uses Hosted UI to display the login web page, but if the user tries to cancel the login via the back button (they want legacy rather than AWS), then the login screen has a busy progress and input is blocked.
It appears that in addition to adding the following to the Manifest:
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
<intent>
<action android:name=
"android.support.customtabs.action.CustomTabsService" />
</intent>
</queries>
<activity
android:name="com.amazonaws.mobile.client.activities.HostedUIRedirectActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="navenioauth" />
</intent-filter>
</activity>
We still need to pass through a null response to the AWS client with:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == AuthClient.CUSTOM_TABS_ACTIVITY_CODE) {
if (data == null) {
// We appear to need to pass through null responses to avoid a busy progress
Timber.d("onActivityResult got null AWS auth response, so passing through to AWS")
AWSMobileClient.getInstance().handleAuthResponse(data)
} else {
Timber.d("onActivityResult got AWS auth response $data")
}
}
}
If we pass non-null CUSTOM_TABS_ACTIVITY_CODE data results then we get an invalid_grant error. However we need to pass the null data to the AWS client, otherwise we get the busy hang, which seems to be created by the AWS Client when triggering the Hosted UI showSignIn().
Which AWS service(s) are affected? Android AWS SDK Cognito 2.53.0
Expected behavior From the documentation it appears that we only need the Manifest entries. We would expect to not need the onActivityResult().
Environment Information (please complete the following information):
Building with Android target SDK / Compile SDK set to 33
AWS Android SDK Version: 2.53.0 "com.amazonaws:aws-android-sdk-cognitoauth:2.53.0" Device: Pixel 4a Android Version: 12 and 13 Specific to simulators: No
At a guess I would say the problem is that doing a back to cancel the login doesn't trigger the showSignIn onError callback unless we add the onActivityResult code, as we use the onError to know that the login was cancelled. `
private fun cognitoLogin() { setLoginInProgress(true)
val hostedUIOptions = HostedUIOptions.builder()
.scopes("openid", "email")
.build()
val signInUIOptions = SignInUIOptions.builder()
.hostedUIOptions(hostedUIOptions)
.build()
AWSMobileClient.getInstance().showSignIn(
this,
signInUIOptions,
object : Callback<UserStateDetails> {
override fun onResult(details: UserStateDetails) {
Timber.d("onResult: ${details.userState}")
viewModel.setupAwsAuthToken()
loginComplete()
}
override fun onError(e: Exception) {
Timber.e("onError: $e")
baseContext.runOnUiThread {
setLoginInProgress(false)
Toast.makeText(baseContext, "Login failed $e", Toast.LENGTH_LONG).show()
}
}
}
)
}`
Hi, we are not able to reproduce the issue as of yet. I see you have setLoginInProgress(true) in your code before showSignIn is called, what does that do?
As I said in my most recent post you are replying to, the problem isn't the busy progress, it's that the AWS SDK isn't calling the onError callback from showSignIn. I'm surprised you see the onError callback, as it is important to know if the showSignIn is cancelled and we have never seen the onError callback unless we add the onActivityResult.
Hi @meavydev, I'm hoping I can clear this up.
I believe the AWS SDK documentation is missing the cancellation scenario that is documented in Amplify (which is using the SDK under the hood). We will leave this ticket assigned as a bug until the documentation is corrected.
See the Amplify documentation here: https://docs.amplify.aws/lib/auth/signin_web_ui/q/platform/android/#add-response-handler. The equivalent needed for the SDK would be:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == AuthClient.CUSTOM_TABS_ACTIVITY_CODE &&
resultCode == Activity.RESULT_CANCELLED) {
// handle cancelled sign in
}
}
One additional point of clarification, the onError callback will still not fire with the above block. You would need to add your setLoginInProgress(false) in the // handle cancelled sign in section. If you would like this specific cancellation to trigger your onError callback, then you were correct that you can call handleAuthResponse with a null intent.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == AuthClient.CUSTOM_TABS_ACTIVITY_CODE &&
resultCode == Activity.RESULT_CANCELLED) {
AWSMobileClient.getInstance().handleAuthResponse(null)
}
}