1

We have an app that uses Cognito to authenticate users and process MFA. We also use CUSTOM_AUTH flow because we need to use CUSTOM_CHALLENGE with defineauth, createauth, and verifyauth lambdas that allow us to handle email MFA that Cognito doesn't support out of the box.

Now I need to implement additional MFA for performing some of the actions in the app, and I'm a bit stuck. The idea is to only trigger one of the MFA challenges (depending on what a user has configured) and apply a few other security controls using CUSTOM_CHALLENGE, but I can't get Cognito to trigger any of its MFA challenges in CUSTOM_AUTH.

To simplify things, imagine we only have a following createauth lambda function:

def lambda_handler(event, context):
    print("received event:", event)
    process_event(event)
    print("response event:", event)
    return event


def process_event(event):
    if len(event["request"]["session"]) == 0:
        event["response"]["issueTokens"] = False
        event["response"]["failAuthentication"] = False
        event["response"]["challengeName"] = "SOFTWARE_TOKEN_MFA"
        return

    s = event["request"]["session"][len(event["request"]["session"]) - 1]

    if s["challengeName"] == "SOFTWARE_TOKEN_MFA" and s["challengeResult"]:
        event["response"]["issueTokens"] = True
        event["response"]["failAuthentication"] = False
        return

    event["response"]["issueTokens"] = False
    event["response"]["failAuthentication"] = True
    

Basically, it assumes that the user has SOFTWARE_TOKEN_MFA enabled (just for testing) and sends SOFTWARE_TOKEN_MFA challenge as the first challenge in the flow. Then it checks that if it has passed validation, issues an access token to the user.

When I start authentication:

aws cognito-idp initiate-auth --auth-flow CUSTOM_AUTH \
        --client-id <client-id> \
        --region ap-southeast-2 \
        --auth-parameters 'USERNAME=<username>'

Everything works as expected:

{
    "ChallengeName": "SOFTWARE_TOKEN_MFA",
    "Session": "<session>",
    "ChallengeParameters": {
        "USERNAME": "<user-id>"
    }
}

However, when I provide a valid code (I can prove it's valid because I've configured MFA for this user in "a normal way" and can log in using the authenticator app codes):

aws cognito-idp respond-to-auth-challenge 
    --client-id <client-id>
    --region ap-southeast-2 
    --challenge-name SOFTWARE_TOKEN_MFA 
    --challenge-responses 'USERNAME=<user-id>,SOFTWARE_TOKEN_MFA_CODE=612345' 
    --session <session>

I get this error:

An error occurred (CodeMismatchException) when calling the RespondToAuthChallenge operation: Invalid code or auth state for the user.

So, basically my question is: is it possible to trigger any of the MFA challenges from the CUSTOM_AUTH flow and if yes, how can I do it without asking the user's password?

I've googled it, tried to find it on stackoverflow, talked to chat gpt, but hasn't found an answer. If you have just any bits of information regarding the matter, I'd appreciate if you shared it.

  • did you able to figure it out, am facing the exact problem now – Kannan T Jun 21 '23 at 14:19
  • Currently, I don't think there's a way to do that in Cognito as it doesn't seem possible to invoke any other authentication flow after CUSTOM_AUTH. Thus, we had to move MFA functionality into our app and stop using Cognito for this purpose – Ivan Tomilov Jun 28 '23 at 19:46
  • yes, we have contacted AWS support team regarding the same, they are taking this as future request, and to implement TOTP flow in custom_auth they don't have docs too, hence we are planning to implement only email MFA – Kannan T Jun 30 '23 at 05:19

0 Answers0