Skip to content
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

Amplify Android "CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE" not handled by Amplify/AWSCognitoAuthPlugin #805

Closed
AntoEko opened this issue Sep 4, 2020 · 15 comments
Assignees
Labels
auth Related to the Auth category/plugins feature-request Request a new feature

Comments

@AntoEko
Copy link

AntoEko commented Sep 4, 2020

Describe the bug
The confirmSignIn method doesn't handle the CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE. It used to be possible with the AWSMobileClient, but it seems it's not possible anymore through Amplify.

To Reproduce
Steps to reproduce the behavior:

  1. Use the signIn(...) method with the CUSTOM_AUTH flow in your amplify-configuration.json file
  2. Try to confirmSignIn(...) with (for example) the code received by SMS. You will have an error:
confirmSignIn called on unsupported operation, please file a feature request

Look at the switch in the confirmSignIn(...) method:

final CognitoIdentityProviderContinuation detectedContinuation;
switch (signInState) {
    case SMS_MFA:
        signInMfaContinuation.setMfaCode(signInChallengeResponse);
        signInMfaContinuation.setClientMetaData(clientMetadata);
        detectedContinuation = signInMfaContinuation;
        signInCallback = new InternalCallback<SignInResult>(callback);
        break;
    case NEW_PASSWORD_REQUIRED:
        ((NewPasswordContinuation) signInChallengeContinuation).setPassword(signInChallengeResponse);
        signInChallengeContinuation.setClientMetaData(clientMetadata);
        detectedContinuation = signInChallengeContinuation;
        signInCallback = new InternalCallback<SignInResult>(callback);
        break;
    case DONE:
        callback.onError(new IllegalStateException("confirmSignIn called after signIn has succeeded"));
        return;
    default:
        callback.onError(new IllegalStateException("confirmSignIn called on unsupported operation, " +
            "please file a feature request"));
        return;
}

Expected behavior
The confirmSignIn(...) method through Amplify / AWSCognitoAuthPlugin should be able to handle the case of CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE.

Additional context
If I try directly to use AWSMobileClient, there is no problem.

@mauerbac
Copy link
Member

mauerbac commented Sep 8, 2020

Thanks @AntoEko . Will have a member of the Android team reproduce this.

@jpignata jpignata transferred this issue from aws-amplify/docs Sep 8, 2020
@richardmcclellan richardmcclellan added auth Related to the Auth category/plugins feature-request Request a new feature labels Sep 9, 2020
@aws-amplify aws-amplify deleted a comment from AntoEko Sep 25, 2020
@JurajBegovac
Copy link

What's going on with this issue?

I ended up by implementing it by myself (still with rxJava2, but should be almost the same with rxJava3). But I would expect it already in the new lib :/

fun RxAuthCategoryBehavior.confirmSignInWithCustomChallenge(secret: String): Single<AuthSignInResult> =
    (Amplify.Auth.getPlugin("awsCognitoAuthPlugin").escapeHatch as AWSMobileClient).rxConfirmSignIn(mutableMapOf(CognitoServiceConstants.CHLG_RESP_ANSWER to secret))
        .map { signInResult -> signInResult.authSignInResult }
/**
 * Rx wrapper for [AWSMobileClient.confirmSignIn]
 */
fun AWSMobileClient.rxConfirmSignIn(signInChallengeResponse: MutableMap<String, String>): Single<SignInResult> =
    Single.create { emitter ->
        confirmSignIn(signInChallengeResponse, object : Callback<SignInResult> {
            override fun onResult(result: SignInResult) {
                emitter.onSuccess(result)
            }

            override fun onError(e: Exception) {
                emitter.onError(e)
            }
        })
    }
/**
 * Copied from [com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin].
 * Same as com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin#convertSignInResult
 */
private val SignInResult.authSignInResult: AuthSignInResult
    @Throws(AuthException::class)
    get() = AuthSignInResult(
        SignInState.DONE == signInState,
        AuthNextSignInStep(
            SignInStateConverter.getAuthSignInStep(signInState),
            if (parameters == null) emptyMap() else parameters,
            codeDetails.authCodeDeliveryDetails
        )
    )

/**
 * Copied from [com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin].
 * Same as com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin#convertCodeDeliveryDetails
 */
private val UserCodeDeliveryDetails?.authCodeDeliveryDetails: AuthCodeDeliveryDetails?
    get() = this?.let {
        AuthCodeDeliveryDetails(
            it.destination,
            AuthCodeDeliveryDetails.DeliveryMedium.fromString(it.deliveryMedium),
            it.attributeName
        )
    }

And then I use it like this:

 RxAmplify.Auth.confirmSignInWithCustomChallenge("[RECEIVED_CODE]")

@edgar-zigis
Copy link
Contributor

edgar-zigis commented Nov 7, 2020

Same issue here. At the moment I handle this via AWSMobileClient

@jamesonwilliams
Copy link
Contributor

jamesonwilliams commented Dec 29, 2020

Strictly speaking, I don't think Amplify Auth supports this right now.

As @edgar-zigis notes, you can use this functionality through Amplify Auth's escape hatch, AWSMobileClient, for the time-being.

  1. Use the escape hatch, as described here.
  2. Implement custom auth with the AWSMobileClient, described here

Update: oh, duh. Didn't see @JurajBegovac's excellent workaround, mentioned above. +1 to it.

@AntoEko
Copy link
Author

AntoEko commented Dec 29, 2020

Yes I'm already using AWSMobileClient but it could be better if Amplify handle this one correctly too... :)

@bostaginting
Copy link

Hi, any update on this issue? :(

@jcowley
Copy link

jcowley commented Mar 12, 2021

So, custom authentication just doesn't work at all on android? And, since amplify-android is a dependency for amplify-flutter, that means that custom auth doesn't work in amplify-flutter either. Yet there is not one word of this in the amplify documentation, and this issue has been sitting here for six months without any movement at all.

Just one more unpleasant surprise waiting for developers who make the unfortunate choice of migrating to Cognito and Amplify and naively expecting that this is a viable solution. If only I could go back in time.

@jamesonwilliams
Copy link
Contributor

@jcowley: That's not correct. Did you try the workaround suggested above?

@jcowley
Copy link

jcowley commented Mar 12, 2021

I'm working on it now, but it is correct: custom authentication is not supported by this library.

@JurajBegovac
Copy link

@jamesonwilliams You're welcome.

@bostaginting Why 👎 on my comment? Without any valid reason from your side besides "Any update?". I would like to see your solution and use it if it's better than mine ✌️

@jcowley Yeah I'm also not sooo happy because I had to do it by myself but there is a solution posted above. You can always adapt it (use it without rx if you want - it's just the code inside the wrapper). But we use it in production and it works fine 🙂

@jamesonwilliams
Copy link
Contributor

custom authentication is not supported by this library.

^ This is correct, but this is not:

custom authentication just doesn't work at all on android

Note that Amplify is distinct from Cognito.

If you want to make arbitrary calls to Cognito to support advanced use cases, please use the Cognito client:

https://github.com/aws-amplify/aws-sdk-android/blob/main/aws-android-sdk-cognitoidentityprovider/src/main/java/com/amazonaws/services/cognitoidentityprovider/AmazonCognitoIdentityProviderClient.java

@jcowley
Copy link

jcowley commented Mar 12, 2021

@JurajBegovac: Yes, appreciate your solution. It's just something I would have expected to either be implemented by the library or documented as a known limitation (including by the dependent aws libraries).

@AntoEko
Copy link
Author

AntoEko commented Mar 15, 2021

If I'm not wrong, with the last Amplify updates, we can now handle CUSTOM_AUTH through Amplify directly.

@liviu-timar
Copy link

liviu-timar commented Mar 30, 2021

Same issue here. At the moment I handle this via AWSMobileClient

Hi @edgar-zigis, @jamesonwilliams, @AntoEko,

Can you tell me more details about how you got it working?

Using AWSMobileClient does not work for either. I'm using a CUSTOM_CHALLENGE sign in state, which is not handled in AWSMobileClient. Here is the code from the sdk. As you can see, it's missing that specific case from the switch. Thanks!

private Runnable _confirmSignIn(final String signInChallengeResponse,  final Callback<SignInResult> callback) {
    return new Runnable() {
        @Override
        public void run() {
            if (signInState == null) {
                callback.onError(new IllegalStateException("Cannot call confirmSignIn(String, Callback) " +
                        "without initiating sign-in. This call is used for SMS_MFA and NEW_PASSWORD_REQUIRED " +
                        "sign-in state."));
                return;
            }

            final CognitoIdentityProviderContinuation detectedContinuation;
            switch (signInState) {
                case SMS_MFA:
                    signInMfaContinuation.setMfaCode(signInChallengeResponse);
                    detectedContinuation = signInMfaContinuation;
                    signInCallback = new InternalCallback<SignInResult>(callback);
                    break;
                case NEW_PASSWORD_REQUIRED:
                    ((NewPasswordContinuation) signInChallengeContinuation)
                            .setPassword(signInChallengeResponse);
                    detectedContinuation = signInChallengeContinuation;
                    signInCallback = new InternalCallback<SignInResult>(callback);
                    break;
                case DONE:
                    callback.onError(new IllegalStateException("confirmSignIn called after signIn has succeeded"));
                    return;
                default:
                    callback.onError(new IllegalStateException("confirmSignIn called on unsupported operation, " +
                            "please file a feature request"));
                    return;
            }

            if (detectedContinuation != null) {
                detectedContinuation.continueTask();
            }
        }
    };
 }

@div5yesh
Copy link
Contributor

If I'm not wrong, with the last Amplify updates, we can now handle CUSTOM_AUTH through Amplify directly.

@AntoEko Yes that is correct. With this PR merged in, confirm sign-in with custom challenge now works with Amplify.

Closing this issue. If you are still experiencing this issue, please let us know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auth Related to the Auth category/plugins feature-request Request a new feature
Projects
None yet
Development

No branches or pull requests

10 participants