There is an option to enable custom authentication flows in Amazon Cognito user pools using AWS Lambda triggers. If you need to implement one extra challenge before allowing users to access the system, Custom Challenge triggers can help you.
Table of Contents
Overview
Again, Amazon Cognito provides an option to trigger AWS Lambdas to customize workflows and the user experience with the system. And custom authentication flow helps to add one or many customs challenges before authorizing a user or generating token in Amazon Cognito
However, we need to force the user to select his account in few applications before we create the OAuth token. Thus, we use a custom authentication flow to add account selection. In addition, you cannot use admin authentication flow with this. Anyhow, there are three event triggers which can be used to add more than one challenges.
Cognit Triggers
It is possible to make advanced customizations to Cognito user pool with AWS Lambda functions to trigger with different events to achieve better user experience. Likewise, you may create an AWS Lambda function in c# or your preferred language that supported by Lambda and then trigger that function during user pool operations.
Furthermore, Custom Authentication Challenge Lambda Triggers are three of those triggers. At least two of them is required if you use two of them.
If you want to know more about Amazon AWS C# Lambda, please check one of my earlier posts – Let’s deploy a simple AWS C# Lambda
Unable to use
You can only use these triggers with Custom Authentication flow
Custom Authentication Flow

These three lambdas trigger issue and verify their own challenges as part of a user pool custom authentication flow to incorporate new challenge types. For instance, these challenge types may include CAPTCHAs or dynamic challenge questions.
Adding three C# Lambda
In this section, I will create three simple amazon lambdas in
All these three lambdas receive JObject as input and also return JObject as output. JObject represents a JSON object that contains a collection of
Define Auth Challenge
This trigger initiates the custom authentication flow. When any request comes with CUSTOM_CHALLENGE auth flow, this lambda will trigger and define what actions are required. Therefore, I have added a minimum c# asp.net core implementation of first lambda below.
public JObject FunctionHandler(JObject input, ILambdaContext context){
var response = input;
var requestSession = input["request"]["session"];
if (requestSession.HasValues)
{
var customChallenge = requestSession
.First(s => s["challengeName"].ToString() == "CUSTOM_CHALLENGE");
if (customChallenge.HasValues && customChallenge["challengeResult"].Value<bool>()){
var selectAccount = requestSession
.First(s => s["challengeMetadata"].ToString() == "SELECT_ACCOUNT");
if (selectAccount.HasValues && selectAccount["challengeResult"].Value<bool>()){
response["response"]["issueTokens"] = true;
response["response"]["failAuthentication"] = false;
}
else{
response["response"]["failAuthentication"] = true;
}
}
else{
ChallengeContinue(response);
}
}
else{
ChallengeContinue(response);
}
return response;
}
private static void ChallengeContinue(JObject response)
{
response["response"]["challengeName"] = "CUSTOM_CHALLENGE";
response["response"]["issueTokens"] = false;
response["response"]["failAuthentication"] = false;
}
It is also confirming the challenge result. Moreover, if all the challenges are fulfilled in the session, this lambda should issueTokens
On the contrary, failAuthentication
should be true to inform Cognito to not to generate any token for the user. You can find the full implementation here.
Create Auth Challenge
Basically, “Create Auth Challenge” will be invoked only if a custom challenge has been specified as part of the Define Auth Challenge trigger. Again, if no custom challenge is specified Cognito will ignore this event
public JObject FunctionHandler(JObject input, ILambdaContext context){
var response = input;
response["response"]["publicChallengeParameters"] = JToken.FromObject(
new Dictionary<string, string>{
{"10", "Demo UK"},
{"20", "Demo Singapore"}
});
response["response"]["privateChallengeParameters"] = JToken.FromObject(20);;
response["response"]["challengeMetadata"] = "SELECT_ACCOUNT";
return response;
}
In this trigger, we defined the publicChallengeParmeters
privateChallengeParameters
Verify Auth Challange
Amazon Cognito invokes this trigger to verify if the response from the end user for a custom Auth Challenge is valid or not
AWS Documentation
public JObject FunctionHandler(JObject input, ILambdaContext context){
var response = input;
var challengeAnswer = input["request"]["challengeAnswer"].ToString();
var privateChallengeParams = input["request"]["privateChallengeParameters"];
if (privateChallengeParams.HasValues){
var answerCorrect = privateChallengeParams
.ToObject<Dictionary<string, string>>()
.Any(a=> a.Key == challengeAnswer);
response["response"]["answerCorrect"] = answerCorrect;
}
return response;
}
Finally, this lambda answerCorrect
Selecting lambdas
Now, go to your Cognito user pool. Select the Triggers tab, and find the following three events and select your published lambdas as below

Sign-in with Custom challenge – Select Account
You can generalize authentication into two common steps with the user pool InitiateAuth and RespondToAuthChallenge API methods.
Client application take two Steps
In this flow, a user authenticates by answering successive challenges until authentication either fails or the user is issued tokens. These two API calls can be repeated to include different challenges.
To illustrate, I have tried a desktop client to verify the workflow.


You can download the source code from my GitHub repository.
Besides, please have a look into the code to find the minimum implementation. Eventually, a user is selecting an account after successfully validating the password. InitiateAuth
and RespondToAuthChallenge
are used to
Read more
In order to get depth knowledge about custom challenge events please check the following AWS Documentation pages
Hi, I was able to configure my app to use custom challenge, but is it possible to use this for only specific condition and use password after that.
I am working on an app where I create user using adminCreateUser and use custom challenge to sign in user. The user redirects from another service using oauth so it make sense to login the user using this custom challenge. But I also want user to set password so that user can sign in using that password in the login form. I am unable to set password for user.
You can try user migration trigger. Check this