Define Auth challenge Lambda trigger (original) (raw)

The define auth challenge trigger is a Lambda function that maintains the challenge sequence in a custom authentication flow. It declares success or failure of the challenge sequence, and sets the next challenge if the sequence isn't yet complete.

Challenge Lambda triggers

The request for this Lambda trigger contains session. The session parameter is an array that contains all of the challenges that are presented to the user in the current authentication process. The request also includes the corresponding result. Thesession array stores challenge details (ChallengeResult) in chronological order. The challenge session[0] represents the first challenge that the user receives.

You can have Amazon Cognito verify user passwords before it issues your custom challenges. Any Lambda triggers associated in the Authentication category of request-rate quotas will run when you perform SRP authentication in a custom challenge flow. Here is an overview of the process:

  1. Your app initiates sign-in by calling InitiateAuth orAdminInitiateAuth with the AuthParameters map. Parameters must include CHALLENGE_NAME: SRP_A, and values forSRP_A and USERNAME.
  2. Amazon Cognito invokes your define auth challenge Lambda trigger with an initial session that contains challengeName: SRP_A and challengeResult: true.
  3. After receiving those inputs, your Lambda function responds withchallengeName: PASSWORD_VERIFIER, issueTokens: false,failAuthentication: false.
  4. If the password verification succeeds, Amazon Cognito invokes your Lambda function again with a new session containing challengeName: PASSWORD_VERIFIER andchallengeResult: true.
  5. To initiate your custom challenges, your Lambda function responds withchallengeName: CUSTOM_CHALLENGE, issueTokens: false, and failAuthentication: false. If you don't want to start your custom auth flow with password verification, you can initiate sign-in with theAuthParameters map including CHALLENGE_NAME: CUSTOM_CHALLENGE.
  6. The challenge loop repeats until all challenges are answered.

The following is an example of a starting InitiateAuth request that precedes custom authentication with an SRP flow.

{
    "AuthFlow": "CUSTOM_AUTH",
    "ClientId": "1example23456789",
    "AuthParameters": {
        "CHALLENGE_NAME": "SRP_A",
        "USERNAME": "testuser",
        "SRP_A": "[SRP_A]",
        "SECRET_HASH": "[secret hash]"
    }
}
Topics

Define Auth challenge Lambda trigger parameters

The request that Amazon Cognito passes to this Lambda function is a combination of the parameters below and thecommon parameters that Amazon Cognito adds to all requests.

JSON

{
    "request": {
        "userAttributes": {
            "string": "string",
                . . .
        },
        "session": [
            ChallengeResult,
            . . .
        ],
        "clientMetadata": {
            "string": "string",
            . . .
        },
        "userNotFound": boolean
    },
    "response": {
        "challengeName": "string",
        "issueTokens": boolean,
        "failAuthentication": boolean
    }
}

Define Auth challenge request parameters

When Amazon Cognito invokes your Lambda function, Amazon Cognito provides the following parameters:

userAttributes

One or more name-value pairs that represent user attributes.

userNotFound

A Boolean that Amazon Cognito populates whenPreventUserExistenceErrors is set toENABLED for your user pool client. A value oftrue means that the user id (username, email address, and other details) did not match any existing users. WhenPreventUserExistenceErrors is set toENABLED, the service doesn't inform the app of nonexistent users. We recommend that your Lambda functions maintain the same user experience and account for latency. This way, the caller can't detect different behavior when the user exists or doesn’t exist.

session

An array of ChallengeResult elements. Each contains the following elements:

challengeName

One of the following challenge types:CUSTOM_CHALLENGE, SRP_A,PASSWORD_VERIFIER, SMS_MFA,EMAIL_OTP,SOFTWARE_TOKEN_MFA,DEVICE_SRP_AUTH,DEVICE_PASSWORD_VERIFIER, orADMIN_NO_SRP_AUTH.

When your define auth challenge function issues aPASSWORD_VERIFIER challenge for a user who has set up multifactor authentication, Amazon Cognito follows it up with anSMS_MFA,EMAIL_OTP, orSOFTWARE_TOKEN_MFA challenge. These are the prompts for a multi-factor authentication code. In your function, include handling for input events fromSMS_MFA,EMAIL_OTP, andSOFTWARE_TOKEN_MFA challenges. You don't need to invoke any MFA challenges in your define auth challenge function.

Important

When your function is determining whether a user has successfully authenticated and you should issue them tokens, always check challengeName in your define auth challenge function and verify that it matches the expected value.

challengeResult

Set to true if the user successfully completed the challenge, or false otherwise.

challengeMetadata

Your name for the custom challenge. Used only ifchallengeName isCUSTOM_CHALLENGE.

clientMetadata

One or more key-value pairs that you can provide as custom input to the Lambda function that you specify for the define auth challenge trigger. To pass this data to your Lambda function, you can use theClientMetadata parameter in the AdminRespondToAuthChallenge and RespondToAuthChallenge API operations. The request that invokes the define auth challenge function doesn't include data passed in the ClientMetadata parameter in AdminInitiateAuth and InitiateAuth API operations.

Define Auth challenge response parameters

In the response, you can return the next stage of the authentication process.

challengeName

A string that contains the name of the next challenge. If you want to present a new challenge to your user, specify the challenge name here.

issueTokens

If you determine that the user has completed the authentication challenges sufficiently, set to true. If the user has not met the challenges sufficiently, set to false.

failAuthentication

If you want to end the current authentication process, set totrue. To continue the current authentication process, set to false.

Define Auth challenge example

This example defines a series of challenges for authentication and issues tokens only if the user has completed all of the challenges successfully. When users complete SRP authentication with the SRP_A and PASSWORD_VERIFIER challenges, this function passes them a CUSTOM_CHALLENGE that invokes the create auth challenge trigger. In combination with our create auth challenge example, this sequence delivers a CAPTCHA challenge for challenge three and a security question for challenge four.

After the user solves the CAPTCHA and answers the security question, this function confirms that your user pool can issue tokens. SRP authentication isn't required; you can also set the CAPTCHA and security question as challenges one & two. In the case where your define auth challenge function doesn't declare SRP challenges, your users' success is determined entirely by their responses to your custom prompts.

Node.js

const handler = async (event) => {
  if (
    event.request.session.length === 1 &&
    event.request.session[0].challengeName === "SRP_A"
  ) {
    event.response.issueTokens = false;
    event.response.failAuthentication = false;
    event.response.challengeName = "PASSWORD_VERIFIER";
  } else if (
    event.request.session.length === 2 &&
    event.request.session[1].challengeName === "PASSWORD_VERIFIER" &&
    event.request.session[1].challengeResult === true
  ) {
    event.response.issueTokens = false;
    event.response.failAuthentication = false;
    event.response.challengeName = "CUSTOM_CHALLENGE";
  } else if (
    event.request.session.length === 3 &&
    event.request.session[2].challengeName === "CUSTOM_CHALLENGE" &&
    event.request.session[2].challengeResult === true
  ) {
    event.response.issueTokens = false;
    event.response.failAuthentication = false;
    event.response.challengeName = "CUSTOM_CHALLENGE";
  } else if (
    event.request.session.length === 4 &&
    event.request.session[3].challengeName === "CUSTOM_CHALLENGE" &&
    event.request.session[3].challengeResult === true
  ) {
    event.response.issueTokens = true;
    event.response.failAuthentication = false;
  } else {
    event.response.issueTokens = false;
    event.response.failAuthentication = true;
  }

  return event;
};

export { handler };