Amazon Cognito
Developer Guide (Version Last Updated: 07/28/2016)

Amazon Cognito User Pool Authentication Flow

Custom Authentication Flow

The custom authentication flow is designed to allow for a series of challenge and response cycles that can be customized to meet different requirements. The flow starts with a call to the InitiateAuth API that indicates the type of authentication that will be used and provides any initial authentication parameters. Amazon Cognito will respond to the InitiateAuth call with either:

  • ID, access, and refresh tokens if the user is signed in

  • A challenge for the user along with a session and parameters

  • An error if the user fails to authenticate

If Amazon Cognito responds to the InitiateAuth call with a challenge, the app will gather more input and call the RespondToAuthChallenge API, providing the challenge responses and passing back the session. Amazon Cognito responds to the RespondToAuthChallenge call similarly to the InitiateAuth call, providing tokens if the user is signed in, another challenge, or an error. If another challenge is returned, the sequence repeats with the app calling RespondToAuthChallenge until the user is signed in or an error is returned. More details are provided in the API documentation for the InitiateAuth and RespondToAuthChallenge APIs.

Amazon Cognito has some built-in AuthFlow and ChallengeName values for a standard authentication flow to validate username and password through the Secure Remote Password (SRP) protocol. This flow is built into the iOS, Android, and JavaScript SDKs for Amazon Cognito. At a high level, the flow starts by sending USER_SRP_AUTH as the AuthFlow to InitiateAuth along with USERNAME and SRP_A values in AuthParameters. If the InitiateAuth call is successful, the response will include PASSWORD_VERIFIER as the ChallengeName and SRP_B in the challenge parameters. The app will then call RespondToAuthChallenge with the PASSWORD_VERIFIER ChallengeName and the necessary parameters in ChallengeResponses. If the call to RespondToAuthChallenge is successful and the user is signed in, the tokens will be returned. If multi-factor authentication (MFA) is enabled for the user, a ChallengeName of SMS_MFA will be returned, and the app can provide the necessary code through another call to RespondToAuthChallenge.

An app can initiate a custom authentication flow by calling InitiateAuth with CUSTOM_AUTH as the Authflow. With a custom authentication flow, the challenges and verification of the responses are controlled through three AWS Lambda triggers. The DefineAuthChallenge Lambda trigger takes as input a session array of previous challenges and responses and outputs the next challenge name and booleans indicating if the user is authenticated (and should be granted tokens) or if the authentication has failed. This Lambda trigger is a state machine that controls the user’s path through the challenges. The CreateAuthChallenge Lambda trigger takes a challenge name as input and generates the challenge and parameters to evaluate the response. CreateAuthChallenge is called when DefineAuthChallenge returns CUSTOM_CHALLENGE as the next challenge, and the next type of challenge is passed in the challenge metadata parameter. The VerifyAuthChallengeResponse Lambda function evaluates the response and returns a boolean to indicate if the response was valid.

A custom authentication flow can also use a combination of built-in challenges such as SRP password verification and MFA via SMS, and custom challenges such as CAPTCHA or secret questions. If you want to include SRP in a custom authentication flow, you need to start with it. To initiate SRP password verification, the DefineAuthChallenge Lambda trigger returns SRP_A as the challenge name and SRP_A in the authentication parameters map. Once the password is verified the DefineAuthChallenge Lambda trigger will be called again with PASSWORD_VERIFIER in the previous challenges array. MFA will be done automatically if it is enabled for a user.

For more information about the Lambda triggers, including sample code, see Customizing User Pool Workflows by Using AWS Lambda Triggers.

Admin Authentication Flow

The APIs described Custom Authentication Flow with the use of SRP for password verification is the recommended approach for authentication. The iOS, Android, and JavaScript SDKs are based on that approach and make it easy to use SRP. However, there is an alternative set of admin APIs designed for use on secure backend servers if you want to avoid the SRP calculations. For these back-end admin implementations, AdminInitiateAuth is used in place of InitiateAuth, and AdminRespondToAuthChallenge is used in place of RespondToAuthChallenge. When using these APIs, the password can be submitted as plain text so the SRP calculations are not needed. For example,

Copy to clipboard
AdminInitiateAuth Request { "AuthFlow":"ADMIN_NO_SRP_AUTH", "AuthParameters":{ "USERNAME":"<username>", "PASSWORD":"<password>" }, "ClientId":"<clientId>", "UserPoolId":"<userPoolId>" }

These admin authentication APIs require developer credentials and use the AWS Signature Version 4 (SigV4) signing process. These APIs are available in standard AWS SDKs including Node.js, which is convenient for use in Lambda functions. In order to use these APIs and have them accept passwords in plain text, you must enable them for the app in the console or by passing ADMIN_NO_SRP_AUTH for the ExplicitAuthFlow parameter in calls to CreateUserPoolClient or UpdateUserPoolClient. The ADMIN_NO_SRP_AUTH AuthFlow is not accepted for the InitiateAuth and RespondToAuthChallenge APIs.

In the AdminInitiateAuth response ChallengeParameters, the USER_ID_FOR_SRP attribute, if present, will contain the user's actual username, not an alias (such as email address or phone number). In your call to AdminRespondToAuthChallenge, in the ChallengeResponses, you'll need to pass this username in the USERNAME parameter.