Skip to content

Cognito custom authentication lamda triggers and an example script for Email MFA.

License

Notifications You must be signed in to change notification settings

iwstkhr/aws-cognito-email-mfa-example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Introduction

Important

Cognito user pools now supports email as a mfa option. For more information, please visit the official announcement page.

Cognito comes with built-in support for the MFA feature, but developers can only choose from either SMS or TOTP options. However, many websites offer an additional email authentication. Developers can implement it using Cognito User Pool custom authentication challenges.

Requirements

When you run the example script, you need to install the following:

Python Scripts

Lambda Layer

src/layers/python/layers/cognito_custom_challenge_helper.py

It is used to make it easy to handle custom challenge requests and responses.

Define Auth Challenge

src/define_auth_challenge/app.py

When starting the custom authentication flow, Cognito invokes "Define Auth challenge Lambda trigger".

Create Auth Challenge

src/create_auth_challenge/app.py

When creating OTP codes which will be sent to users in the authentication challenge flow, Cognito invokes "Create Auth challenge Lambda trigger".

Environment variables CODE_LENGTH and EMAIL_SENDER in the script are specified by an AWS SAM template described later.

Tip

By placing the OTP code issued from the last session into the response metadata, users can reuse the OTP code during the same authentication challenge session.

You can configure authentication flow session duration in Cognito.

Verify Auth Challenge

src/verify_auth_challenge/app.py

When verifying OTP codes, Cognito invokes "Verify Auth challenge Lambda trigger".

Creating AWS Resources

AWS SAM Template

template.yaml

Key Points:

  • To enable custom authentication challenges, set ALLOW_CUSTOM_AUTH within ExplicitAuthFlows.
  • Please ensure that CognitoEvent within each AWS::Serverless::Function is linked to the Lambda functions to serve as Cognito Lambda triggers.
  • Setting Policies in the CreateAuthChallenge function is required for sending emails using Amazon SES.

Build and Deploy

Replace <YOUR_SES_EMAIL_SENDER> with a desired email address as a sender, and build and deploy with the following command. If you want to change the length of OTP codes, also specify CodeLength parameter.

sam build
sam deploy --parameter-overrides EmailSender=<YOUR_SES_EMAIL_SENDER>
# sam deploy --parameter-overrides EmailSender=<YOUR_SES_EMAIL_SENDER> CodeLength=10

When completed, the following AWS resources are created in your AWS environment.

Logical ID Type
CognitoUserPool AWS::Cognito::UserPool
CognitoUserPoolClient AWS::Cognito::UserPoolClient
LambdaLayer AWS::Lambda::LayerVersion
CreateAuthChallenge AWS::Lambda::Function
DefineAuthChallenge AWS::Lambda::Function
VerifyAuthChallenge AWS::Lambda::Function
CreateAuthChallengeCognitoPermission AWS::Lambda::Permission
DefineAuthChallengeCognitoPermission AWS::Lambda::Permission
VerifyAuthChallengeCognitoPermission AWS::Lambda::Permission
CreateAuthChallengeRole AWS::IAM::Role
DefineAuthChallengeRole AWS::IAM::Role
VerifyAuthChallengeRole AWS::IAM::Role

Testing

Replace <YOUR_USER_POOL_ID> and <YOUR_EMAIL> with your values, and create a Cognito testing user with the following command.

POOL_ID=<YOUR_USER_POOL_ID>
EMAIL=<YOUR_EMAIL>

# Add a Cognito user.
aws cognito-idp admin-create-user \
  --user-pool-id $POOL_ID \
  --username $EMAIL

# Make the user confirmation status "Confirmed"
echo -n 'Password: '
read password
aws cognito-idp admin-set-user-password \
  --user-pool-id $POOL_ID \
  --username $EMAIL \
  --password $password \
  --permanent

To test the email MFA, run the following command.

cd src/example
pip install -r requirements.txt
python main.py \
  --pool-id <YOUR_USER_POOL_ID> \
  --client-id <YOUR_CLIENT_ID> \
  --username <YOUR_EMAIL> \
  --password <YOUR_PASSWORD>

The src/example/main.py uses the following libraries to calculate values needed by SRP - Secure Remote Password.

You may also refer to the AWS official code example.

Cleaning Up

Clean up the provisioned AWS resources with the following command.

sam delete

(Optional) Unit Testing

Run the following command in your shell.

export PYTHONPATH=$PYTHONPATH:$(pwd)/src:$(pwd)/src/layers/python
pytest -vv

About

Cognito custom authentication lamda triggers and an example script for Email MFA.

Topics

Resources

License

Stars

Watchers

Forks

Languages