AWS Security Blog
How to configure Duo multi-factor authentication with Amazon Cognito
October 23: This post has been updated to utilize Duo Web v4 SDK and OIDC approach for integration with Duo two-factor authentication.
Adding multi-factor authentication (MFA) reduces the risk of user account take-over, phishing, and password theft. Adding MFA while providing a frictionless sign-in experience requires you to offer a variety of MFA options that support a wide range of users and devices. Let’s see how you can achieve that with Amazon Cognito and Duo MFA.
Amazon Cognito user pools are user directories that are used by Amazon Web Services (AWS) customers to manage the identities of their customers and to add sign-in, sign-up and user management features to their customer-facing web and mobile applications. Duo Security is an APN Partner that provides unified access security and multi-factor authentication solutions.
In this blog post, I show you how to use Amazon Cognito custom authentication flow to integrate Duo MFA into your sign-in flow and offer a wide range of MFA options to your customers. Some second factors available through Duo MFA are mobile phone SMS passcodes, approval of login via phone call, push-notification-based approval on smartphones, biometrics on devices that support it, and security keys that can be attached via USB.
How it works
Amazon Cognito user pools enable you to build a custom authentication flow that authenticates users based on one or more challenge/response cycles. You can use this flow to integrate Duo MFA into your authentication as a custom challenge.
Duo Web offers a software development kit to make it simpler for you to integrate your web applications with Duo MFA. You need an account with Duo and an application to protect (which can be created from the Duo admin dashboard). When you create your application in the Duo admin dashboard, note the client ID, client secret, and API hostname. These details are the primary factors used to integrate your Amazon Cognito user pool with Duo MFA.
Note: Client ID and client secret are referred to as Duo keys.
Duo MFA will be integrated into the sign-in flow as a custom challenge. To do that, you need to generate a redirect URL and a state value using Duo APIs and use those to load Duo MFA and request the user’s second factor. When the challenge is answered by the user, a response with duo_code and state value is returned to your application’s callback URL and sent to Amazon Cognito for verification. If the response is valid, then the MFA challenge is successful.
Let’s take a closer look at the sequence of calls and components involved in this flow.
Implementation details
In this section, I walk you through the end-to-end flow of integrating Duo MFA with Amazon Cognito using a custom authentication flow. To help you with this integration, I built a demo project that provides deployment steps and sample code to create a working demo in your environment.
Create and configure a user pool
The first step is to create the AWS resources needed for the demo. You can do that by deploying the AWS CloudFormation stack as described in the demo project.
A few implementation details to be aware of:
- The template creates an Amazon Cognito user pool, application client, and AWS Lambda triggers that are used for the custom authentication.
- The template also accepts the Duo client ID, client secret, and Host API name as inputs. For security, the parameters are masked in the AWS CloudFormation console. These parameters are stored in a secret in AWS Secrets Manager with a resource policy that allows the relevant Lambda functions read access to that secret.
- Duo keys are loaded from Secrets Manager at the initialization of create auth challenge and verify auth challenge Lambda triggers to be used to create redirect_url and verify duo_code.
Authentication flow
The preceding sequence diagram (Figure 1) illustrates the sequence of calls to sign in a user, which are as follows:
- In your application, the user is presented with a sign-in UI that captures the username and password and starts the sign-in flow. A script—running in the browser—starts the sign-in process using the Amazon Cognito authenticateUser API with CUSTOM_AUTH set as the authentication flow. This validates the user’s credentials using Secure Remote Password (SRP) protocol and moves on to the second challenge if the credentials are valid.
- After the SRP challenge step, the define auth challenge Lambda trigger returns CUSTOM_CHALLENGE and this moves control to the create auth challenge trigger.
- The create auth challenge Lambda trigger first builds a Duo auth client using the Duo keys, Duo Host API, and application callback URL, then uses the Duo auth client to generate a Duo auth state and an auth URL with the username. This Lambda trigger returns the auth URL and state value as a challenge to the client. Here is a sample code of what create auth challenge should look like:
- The client stores the Duo state value and then redirects the user to the returned Duo auth URL. This is done on the client side as follows:
- Through the redirected Duo page, the user can set up their MFA preferences and respond to an MFA challenge. After a successful MFA setup, a Duo Auth code and the state value from the Duo Web library will be returned to the client application’s callback URL that was provided in duo_universal’s new client call in the create auth challeng Lambda trigger.
- The client sends the Duo auth code response to Amazon Cognito as a challenge response.
- Amazon Cognito sends the response to the verify auth challenge Lambda trigger, which uses Duo keys and username to verify the response.
- Validation results and current state are passed once again to the define auth challenge Lambda trigger. If the user response is valid, then the Duo MFA challenge is successful. You can then decide to introduce additional challenges to the user or issue tokens and complete the authentication process.
Note: The authenticateUser API automatically starts the authentication process with SRP. The first challenge that’s sent to Amazon Cognito is SRP_A. This is followed by PASSWORD_VERIFIER to verify the user’s credentials.
Conclusion
As you build your mobile or web application, keep in mind that using multi-factor authentication is an effective and recommended approach to protect your customers from account take-over, phishing, and the risks of weak or compromised passwords. Making multi-factor authentication simple for your customers enables you to offer authentication experience that protects their accounts but doesn’t slow them down.
Visit the security pillar of AWS Well-Architected Framework to learn more about AWS security best practices and recommendations.
In this blog post, I showed you how to integrate Duo MFA with an Amazon Cognito user pool. Visit the demo application and review the code samples in it to learn how to integrate this with your application.
If you have feedback about this post, submit comments in the Comments section below. If you have questions about this post, start a new thread on the Amazon Cognito forum or contact AWS Support.
Want more AWS Security how-to content, news, and feature announcements? Follow us on Twitter.