Users can be migrated to Cognito User Pools at the time of sign in or during the forgot-password flow. In fact Cognito Trigger – User migration lambda is the tool, that should be used.
However, my company decided to use Amazon Cognito as our authentication service provider. They have more than 40,000 existing users. To add users to user pool, we decided to use Cognito lambda trigger User Migration instead of importing users.
Table of Contents
Basic Introduction to Cognito
Cognito provides authentication, authorization, and user management for applications. User pool is one of the two main components of Amazon Cognito. And also, user pools are user directories that provide sign-up and sign-in options for your app users. Users can sign in directly with his credentials, or through social networks such as Facebook, Twitter or Google.
Moreover, you can migrate users from your existing user directory into Amazon Cognito User Pools at the time of sign-in or during the forgot-password flow with this Lambda trigger. Here, I am trying to demonstrate a simple user migration lambda trigger that adds users based on some predefined password
Configuring User Pool Migrate User Lambda
I am assuming that you are already familiar with Dotnet core 2.2, AWS Lambda Functions, Amazon Cognito, User Pool, and Cognito Triggers.
Basically, you can use AWS Lambda triggers to customize workflows and the user experience with Amazon Cognito. And also, Cognito passes event information to your Lambda function which returns the same event object back to Amazon Cognito with any changes in the response.
User Pool Lambda Triggers
A user migration Lambda trigger allows easy migration of users from your existing user management system into the Cognito user pool. In addition, a
Amazon Cognito invokes this trigger when a user does not exist in the user pool at the time of sign-in with a password, or in the forgot-password flow. After the Lambda function returns successfully, Amazon Cognito creates the user in the user pool.
Migrate User Lambda Trigger
I am using C# dotnet core 2.2 to build Amazon Lambda Function that will be triggered when user sign-in
Migrate User Lambda in C#
First, you need create a dotnet core 2.2 project. Add following two packages
- Amazon.Lambda.Core
- Amazon.Lambda.Serialization.Json
Second, Add a Function class, and the class must contain the FunctionHandler method. The assembly should be serialized with LambdaSerializer. Find an example below.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))] namespace LambdaUserMigration { public class Function { public JObject FunctionHandler(JObject input, ILambdaContext context){ var response = input; var userName = input["userName"]?.ToString(); var password = input["request"]["password"]?.ToString(); if (!string.IsNullOrWhiteSpace(userName) && password == "UserMigration"){ response["response"]["userAttributes"] = JToken.FromObject(new Dictionary<string, object>() { {"username", userName}, {"email", userName}, {"email_verified", true} }); response["response"]["forceAliasCreation"] = false; response["response"]["finalUserStatus"] = "CONFIRMED"; response["response"]["messageAction"] = "SUPPRESS"; response["response"]["desiredDeliveryMediums"] = JArray.FromObject(new[] {"EMAIL"} ); } return response; } } }
Parameter – Datatype JObject
The function has two parameters. And the first one is JObject which is basically the triggered event passed by Cognito. As I mentioned above, you need to send the same event back as the response, for this reason, I copy the input as values as a response and modified its properties if the request is valid, otherwise, I will return the request as a response. Please find the full event below
{
"userName": "string",
"request": {
"password": "string"
},
"response": {
"userAttributes": {
"string": "string",
…
},
"finalUserStatus": "string",
"messageAction": "string",
"desiredDeliveryMediums": [ "string", … ],
"forceAliasCreation": boolean
}
userAttributes
A mandatory field that contains at least one name-value pairs representing user attributes. As this will be stored in the user profile in the user pool.
finalUserStatus
During sign-in, this attribute can be set to
finalUserStatus – AWS DocumentationCONFIRMED
, or not set, to auto-confirm your users and allow them to sign-in with their previous passwords. This is the simplest experience for the user.
If this attribute is set to RESET_REQUIRED, the user is required to change his or her password immediately after migration at the time of sign-in, and your client app needs to handle thePasswordResetRequiredException
during the authentication flow.
forceAliasCreation
You can set true or false.
- The phone number or email address specified in the UserAttributes parameter already exists as an alias with a different user and the value assigned is true then the API call will migrate the alias from the previous user to the newly created user. The previous user will no longer be able to log in using that alias.
- Setting “false” will return an error to the client app if the user already exists.
- If this attribute is not included in the response, it will consider as “false”.
desiredDeliveryMediums
This will define how the user will get a welcome message. Accepted values are EMAIL or SMS. If this is not added to the response it will use SMS
These are few important attributes for a response from User Migration Lambda Trigger
Add to User Pool
So lets add a user pool Lambda trigger with the console
- To start with, you can upload the c#
dotnet core lambda function using the Lambda console in order to know how please find one of my earlier posts Deploy a simple AWS C# Lambda - Now, hook up the Lambda function to the “migrate trigger” in Cognito from Amazon Cognito console
- Select Manage User Pools.
- Choose an existing user pool from the list, or create a user pool
- In your user pool, choose the Triggers tab from the navigation bar.
- Choose a User Migration Lambda trigger and choose your Lambda function from the Lambda function drop-down list.
- Choose Save changes.
Now time to test your lambda
Misc
Finally, some miscellaneous information that i found helpful.
Migrate User Lambda Trigger Sources are
- UserMigration_Authentication – User migration at the time of sign in.
- UserMigration_ForgotPassword – User migration during forgot-password flow.
Moreover, If any error occurs during migration, the apps will get error responses from the Amazon Cognito User Pools API, and the user might or might not have been created in your user pool.
Your app sends the username and password to Amazon Cognito. If your app has a native sign-in UI and uses the Cognito Identity Provider SDK, your app must use the USER_PASSWORD_AUTH flow, in which the SDK sends the password to the server (your app must not use the default USER_SRP_AUTH flow since the SDK does not send the password to the server in the SRP authentication flow). The USER_PASSWORD_AUTH flow is enabled by setting AuthenticationDetails.authenticationType to “USER_PASSWORD”.
Second Steps during sign-in
So when you are sending
Furthermore, you can download a sample migrate user lambda trigger from my
Read More about user migration
I recommend to go through the following to AWS documentation to understand more about migration users to user pool
- Importing Users into User Pools With a User Migration Lambda Trigger
- Migrate User Lambda Trigger
- AWS Mobile Blog – Migrating Users to Amazon Cognito User Pools
You can read about the user pool triggers here. To know about other lambda triggers please check User Pool Lambda Trigger Sources