Skip to content

How to reduce the number of OTP sent for authentication when user has expired password

0

AWS Cognito sends 2 OTP whenever password expired

Currently authentication workflow uses Lambda triggers and MFA is set optional.

Pre authentication Lambda Trigger

Attached : lambda-expirationPasswordTimeChecker

The provided script is designed to enforce custom password expiration logic for users when password has 3 month old and perform reset password.

Here's an explanation of its use case and purpose:

Custom Password Expiration Policy:

While Cognito handles "Forgot Password" functionality, it doesn’t natively enforce password expiration for permanent passwords.

This script ensures that if a user's password is older than the defined expiration policy (e.g., 90 days), the system resets their password programmatically.

Security Compliance:

Some organizations or tenants might have regulatory or internal compliance requirements mandating periodic password updates (e.g., every 90 days).

The script enables this functionality by leveraging Cognito and maintaining expiration data as a custom attribute in Cognito (custom:expirationDatetime).

Audit and Tenant-Specific Logic:

The script retrieves tenant-specific and user-specific information from DynamoDB tables (TENANT_POOLS_TABLE_NAME and USERS_TABLE_NAME).

These data are logged for audit purposes, ensuring administrators can monitor which user's password was reset and which tenant they belong to

Pre token generation Lambda Trigger & Post Confirmation Lambda trigger

Attached : lambda-expirationPasswordTimeUpdater

Similar to above, the provided script is designed to enforce custom password expiration logic for users when change password.

Set the EXPIRATION_PASSWORD_MONTHS = 3

Key Differences

  1. PreAuthentication Lambda Trigger (Cognito) Purpose: Runs custom logic as part of the authentication flow in AWS Cognito.

When It Runs:

Executed after Cognito verifies a user's credentials but before it issues tokens (ID, access, or refresh tokens).

Allows you to perform checks (e.g., enforce password expiration policies, account state validation) or log events (like successful logins).

Use Cases:

Enforcing business logic like password expiration, account suspension, etc.

Enhancing security by validating or altering login attempts.

Tracking user-specific attributes or events in an external system (like DynamoDB, for audit purposes).

  1. Lambda Authorizer (API Gateway) Purpose: Verifies and validates API requests before granting access to specific resources.

When It Runs:

Executed by API Gateway after receiving an API request and before invoking the target service or Lambda function.

Usually checks a Cognito-issued token (ID or access token) in the API request header to validate a user's access to the API.

Use Cases:

Validating JWT tokens and confirming claims (e.g., roles or permissions).

Enforcing additional resource-level access controls (e.g., tenant isolation or access limits).

Retrieving and attaching user context (e.g., permissions, tenant info) for the backend to consume.Temporary vs. Permanent Passwords:

Temporary passwords created via AdminCreateUser or similar functions have a 90-day expiration.

A new password set through "Forgot Password" is permanent and does not have an expiration timeline unless enforced by a custom policy.

1 Answer
0

When a user's password expires in Amazon Cognito and MFA is enabled, you may be experiencing multiple OTP (One-Time Password) messages being sent during the authentication flow. This happens because the system is sending one OTP for the password reset process and another for the MFA verification.

To reduce the number of OTPs sent when a user has an expired password, you can implement the following solutions:

  1. Modify your Pre-Authentication Lambda Trigger: Instead of forcing an immediate password reset when detecting an expired password, you could set a flag in the user attributes indicating the password needs to be changed at the next successful authentication. This way, the user completes their MFA authentication first, and then is prompted to change their password afterward.

  2. Use AdminResetUserPassword with care: If your lambda-expirationPasswordTimeChecker is using AdminResetUserPassword to force password resets, consider that this immediately invalidates the user's current authentication attempt and triggers a separate password reset flow, which can result in multiple OTPs.

  3. Consolidate the authentication flow: Adjust your authentication flow to handle both the password reset and MFA verification in a single sequence. You can use custom authentication challenges to manage this process more efficiently.

  4. Consider using TOTP (Time-based One-Time Password) MFA: If appropriate for your use case, software token MFA (TOTP) using authenticator apps doesn't require sending additional OTPs via SMS or email. Users would generate the code from their authenticator app instead.

  5. Adjust the password expiration timing: You could modify your EXPIRATION_PASSWORD_MONTHS setting to create a grace period where users are warned about upcoming password expiration but can still authenticate normally for a short time.

Remember that your custom password expiration implementation using Lambda triggers gives you flexibility to control exactly when and how the password reset occurs in relation to the MFA verification, allowing you to optimize the user experience.
Sources
Cognito_MFA_Reset_or_reconfigure_for_user | AWS re:Post
Authentication with Amazon Cognito user pools - Amazon Cognito
Adding MFA to a user pool - Amazon Cognito
How can I enforce password expiration in Amazon Cognito User Pools | AWS re:Post

answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.