Skip to content

[Auth] UserCancelledException occurs on sign-in after sign-out #3167

@zeroarst

Description

@zeroarst

Before opening, please confirm:

Language and Async Model

Kotlin - Coroutines

Amplify Categories

Authentication

Gradle script dependencies

Amplify version: 2.30.4

Dependencies:

aws-amplify-auth-cognito = { group = "com.amplifyframework", name = "aws-auth-cognito", version.ref = "aws-amplify" }
aws-amplify-core-kotlin = { group = "com.amplifyframework", name = "core-kotlin", version.ref = "aws-amplify" }

Environment information

Details
Build time:    2025-02-25 09:22:14 UTC
Revision:      073314332697ba45c16c0a0ce1891fa6794179ff

Kotlin:        2.0.21
Groovy:        3.0.22
Ant:           Apache Ant(TM) version 1.10.15 compiled on August 25 2024
Launcher JVM:  17.0.2 (Oracle Corporation 17.0.2+8-LTS-86)
Daemon JVM:    C:\Program Files\Java\jdk-17.0.2 

Please include any relevant guides or documentation you're referencing

No response

Describe the bug

The user can sign in successfully using SSO on the first attempt without any issues.

After logging in, when the user taps Sign Out in the app, we call Amplify.Auth.signOut(). The sign-out completes successfully and returns AWSCognitoAuthSignOutResult.CompleteSignOut (see annotation 1 below).

The user is then redirected to the login screen. However, when attempting to sign in again using the same SSO flow, the following error is returned:

UserCancelledException{
  message=The user cancelled the sign-in attempt, so it did not complete.,
  cause=null,
  recoverySuggestion=To recover: catch this error, and show the sign-in screen again.
}

(see annotation 2 below).

During the second login attempt, a WebView seems to briefly open and immediately closes.

Image

This appears similar to issue #2591, but adding a delay does not resolve the problem.

Reproduction steps

  1. Log in using SSO via
    Amplify.Auth.signInWithSocialWebUI(provider: AuthProvider, callingActivity: Activity, options: AuthWebUISignInOptions)
  2. Login succeeds.
  3. Log out by calling Amplify.Auth.signOut(global = false).
  4. Attempt to log in again using the same SSO method.
  5. A UserCancelledException is thrown.

Debugging Details

I added breakpoints in both CustomTabsManagerActivity.kt and HostedUIRedirectActivity.kt to investigate the flow.

First Login (Works as Expected)

  1. User enters an email in the app, we check if is SSO login. If is SSO, we call signInWithSocialWebUI(provider: AuthProvider, callingActivity: Activity, options: AuthWebUISignInOptions)
  2. CustomTabsManagerActivity.onCreate is called
  3. CustomTabsManagerActivity.onResume is called (customTabsLaunched == false).
  4. A Webview is opened showing SSO login page. User enters email and password. User logs in sucessfully.
  5. HostedUIRedirectActivity.onCreate is called.
  6. HostedUIRedirectActivity.onResume is called, which invokes Amplify.Auth.handleWebUISignInResponse(intent), then finish().
  7. CustomTabsManagerActivity.onResume is called again (customTabsLaunched == true) with a non-null intent.data containing the callback URL.
  8. User clicks the log-out button in the app. App calls Amplify.Auth.signOut(global = false)
  9. CustomTabsManagerActivity.onCreated is called
  10. CustomTabsManagerActivity.onResume is called (customTabsLaunched == false)
  11. A Webview is opened and closed quickly.
  12. HostedUIRedirectActivity.onCreated is called.
  13. HostedUIRedirectActivity.onResume is called, which invokes Amplify.Auth.handleWebUISignInResponse(intent), then finish().

Second Login (After Logout – Fails)

  1. User enters an email in the app, we check if it is SSO login. If is SSO, we call signInWithSocialWebUI(provider: AuthProvider, callingActivity: Activity, options: AuthWebUISignInOptions)
  2. CustomTabsManagerActivity.onCreate is called
  3. CustomTabsManagerActivity.onResume is called (customTabsLaunched == false).
  4. No sure if a WebView is open. HostedUIRedirectActivity is not created.
  5. CustomTabsManagerActivity.onResume is called immediately (customTabsLaunched == true) with intent.data == null.
  6. This results in the sign-in being treated as cancelled, triggering UserCancelledException.

It’s unclear why HostedUIRedirectActivity is skipped on the second login attempt after a successful sign-out.

Code Snippet

SSO Login

private suspend fun performSignIn(authProviderName: String, activity: androidx.appcompat.app.AppCompatActivity): Result<SSOLoginData> {
    val result = Amplify.Auth.signInWithSocialWebUI(
        provider = AuthProvider.custom(authProviderName),
        callingActivity = activity,
        AWSCognitoAuthWebUISignInOptions.builder()
            .preferPrivateSession(true)
            .build()
    )

    if (!result.isSignedIn) {
        error("AuthSignInResult.isSignedIn is false")
    }

    val ssoLoginData = extractSSOLoginData(
        fetchAmplifyAuthState().getOrThrow()
    )
    Timber.d("SSO login with Web UI succeeded: $ssoLoginData")
    return Result.success(ssoLoginData)
}

Callback activity configuration

<activity
    android:name="com.amplifyframework.auth.cognito.activities.HostedUIRedirectActivity"
    android:exported="true">
    <intent-filter android:label="SSO Login">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:host="app"
            android:pathPrefix="/sign-in"
            android:scheme="thrive" />
    </intent-filter>
    <intent-filter android:label="SSO Logout">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:host="app"
            android:pathPrefix="/sign-out"
            android:scheme="thrive" />
    </intent-filter>
</activity>

Metadata

Metadata

Assignees

No one assigned

    Labels

    authRelated to the Auth category/pluginsbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions