If you want to set up TOTP software token MFA in your user pool, your user needs to signs in with a user name and password, then uses a TOTP to complete authentication.
After your user sets and verifies a user name and password, they can activate a TOTP software token for MFA.
You can activate TOTP MFA for your user pool in the Amazon Cognito console, or you can use Amazon Cognito API operations. At the user pool level, you can call SetUserPoolMfaConfig to configure MFA and enable TOTP MFA.
Table of Content :
- Introduction
- What is Amazon Cognito?
- Maven dependencies
- Create CognitoClient Instance
- Enable software token MFA for pool
- Associate the TOTP Token
- Set google auth using the secret key
- Verify the TOTP Token
- Set user MFA prefernces
- Sign in with TOTP MFA
- Questions related to AWS Cognito TOTP Software Token MFA Using Java
- Summary
Configuring TOTP for your user is a multi-step process where your user receives a secret code that they validate by entering a one-time password. Next, you can enable TOTP MFA for your user or set TOTP as the preferred MFA method for your user.
Maven dependencies
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-core</artifactId>
<version>1.11.764</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-cognitoidp</artifactId>
<version>1.11.764</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.360</version>
</dependency>
Create CognitoClient Instance
public static AWSCognitoIdentityProvider getAWSCognitoIdentityClient() {
System.setProperty("aws.accessKeyId", "-- your accessKey Id--");
System.setProperty("aws.secretKey", "-- your secret Key--");
AWSCognitoIdentityProvider cognitoClient = AWSCognitoIdentityProviderClientBuilder.standard().withRegion(Regions.AP_SOUTH_1).withCredentials(new SystemPropertiesCredentialsProvider()).build();
return client;
}
If TOTP software token MFA isn't enabled for the user pool, users can't associate or verify with the token. They receive a SoftwareTokenMFANotFoundException exception, as follows: "Software Token MFA has not been enabled by the user pool."
Enable software token MFA for pool
You can enable TOTP MFA for your user pool in the Amazon Cognito console, through the Amazon Cognito hosted UI, or using Amazon Cognito APIs. At the user pool level, you can configure MFA and enable TOTP MFA by calling SetUserPoolMfaConfig.
Associate the TOTP Token | AWS Cognito - Enable MFA per user
When your user chooses TOTP software token MFA, call AssociateSoftwareToken to return a unique generated shared secret key code for the user account. The request for this API method takes an access token or a session string, but not both. As a convenience, you can distribute the secret key as a quick response (QR) code.
public InitiateAuthResult loginUser(final String username, final String password) {
final AWSCognitoIdentityProvider provider = getAWSCognitoIdentityClient();
final Map<String String> authParams = new HashMap<String >();
authParams.put("USERNAME", username);
authParams.put("PASSWORD", password);
final InitiateAuthRequest initiateAuthRequest = new InitiateAuthRequest().withClientId(clientId)
.withAuthFlow(AuthFlowType.USER_PASSWORD_AUTH).withAuthParameters(authParams);
final InitiateAuthResult result = provider.initiateAuth(initiateAuthRequest);
log.info("Result Challenge is : " + result.getChallengeName());
return result;
}
final InitiateAuthResult result = loginUser(username, password);
public static String getSecretForAppMFA(final InitiateAuthResult result) {
final AWSCognitoIdentityProvider provider = getAWSCognitoIdentityClient();
final AssociateSoftwareTokenRequest associateSoftwareTokenRequest = new AssociateSoftwareTokenRequest();
associateSoftwareTokenRequest.setAccessToken(result.getAuthenticationResult().getAccessToken());
associateSoftwareTokenRequest.setSession(result.getSession());
final AssociateSoftwareTokenResult associateSoftwareTokenResult = provider
.associateSoftwareToken(associateSoftwareTokenRequest);
associateSoftwareTokenResult.getSecretCode();
log.info("this is a secret code we need to put in google Authenticator app : steps given below");
log.info(associateSoftwareTokenResult.getSecretCode());
log.info("getSecretForAppMFA : secret code generated successfully.This code you have to put in Sodtware MFA app like google Auth.");
return associateSoftwareTokenResult.getSecretCode();
}
Set google auth using the secret key
In google Auth, we have to enter generated secret code as,
Account Name - your user name
Your key - Secrete returned by above
Type of Key - Time-Based
Verify the TOTP Token
After a new TOTP account is associated with your app, it generates a temporary password(6 digit code).
Your user enters the temporary password into your app, which responded with a call to VerifySoftwareToken. On the Amazon Cognito service server, a TOTP code is generated and compared with your user's temporary password. If they match, then the service marks it as verified.
If the code is correct, check that the time used is in the range and within the maximum number of retries. Amazon Cognito also accepts TOTP tokens that are one 30 second window early or late to account for clock skew. If your user passes all of the steps, the verification is complete.
Or, if the code is wrong, the verification cannot be finished and your user can either try again or cancel. We recommend that your user sync the time of their TOTP-generating app.
In our case we are using AWS Java SDK, so we need to call loginUser(username, password, code from google)
public static VerifySoftwareTokenResult verifySoftwareTokenForAppMFA(final AWSCognitoIdentityProvider provider,
final InitiateAuthResult result, final String code) throws Exception {
try {
final VerifySoftwareTokenRequest verifySoftwareTokenRequest = new VerifySoftwareTokenRequest();
if (result.getAuthenticationResult() != null) {
verifySoftwareTokenRequest.setAccessToken(result.getAuthenticationResult().getAccessToken());
}
if (result.getSession() != null) {
verifySoftwareTokenRequest.setSession(result.getSession());
}
verifySoftwareTokenRequest.setUserCode(code);// 6 digit code from google Auth
final VerifySoftwareTokenResult verifySoftwareTokenResult = provider
.verifySoftwareToken(verifySoftwareTokenRequest);
log.info("Software token verified");
log.info(verifySoftwareTokenResult.getSession());
return verifySoftwareTokenResult;
} catch (final Exception ex) {
log.error(ex.getMessage());
}
}
}
Set user MFA prefernces
After verifying verifySoftwareTokenResult we need to set user MFA preferences as given below.
public static void registerSoftwareMFAPreferences(final String username, final String userPoolId) {
final AWSCognitoIdentityProvider provider = getAWSCognitoIdentityClient();
final SoftwareTokenMfaSettingsType softwareTokenMfaSettings1 = new SoftwareTokenMfaSettingsType()
.withPreferredMfa(true).withEnabled(true);
final AdminSetUserMFAPreferenceRequest adminSetUserMFAPreferenceRequest = new AdminSetUserMFAPreferenceRequest()
.withSoftwareTokenMfaSettings(softwareTokenMfaSettings1).withUsername(username)
.withUserPoolId(userPoolId);
provider.adminSetUserMFAPreference(adminSetUserMFAPreferenceRequest);
log.info("SoftwareMFAPreferences set suucessfully");
}
Sign in with TOTP MFA
Your user enters their user name and password to sign in to your client app.
The TOTP MFA challenge is invoked and your user is prompted by your app to enter a temporary password.
Your user gets the temporary password from an associated TOTP-generating app.
Your user enters the TOTP code into your client app. Your app notifies the Amazon Cognito service to verify it. For each sign-in, RespondToAuthChallenge should be called to get a response to the new TOTP authentication challenge.
If the token is verified by Amazon Cognito, the sign-in is successful and your user continues with the authentication flow.
When we verified Verify TOTP Token and set the MFA preferences, we set go.our software MFA is set for given user.
We can log in using username, password, and MFA code from google authenticator.
here is the final code for login.
final AWSCognitoIdentityProvider provider = getAWSCognitoIdentityClient();
final InitiateAuthResult result = loginUser(username, password);
if (result.getChallengeName() != null && result.getChallengeName().equals("SOFTWARE_TOKEN_MFA")) {
log.info("SOFTWARE_TOKEN_MFA challenge is generated");
final Map<String String> challengeResponses = new HashMap<String String>();
challengeResponses.put("USERNAME", username);
challengeResponses.put("SOFTWARE_TOKEN_MFA_CODE", mfaCode);
final RespondToAuthChallengeRequest respondToAuthChallengeRequest = new RespondToAuthChallengeRequest()
.withChallengeName(ChallengeNameType.SOFTWARE_TOKEN_MFA).withClientId(clientId)
.withChallengeResponses(challengeResponses).withSession(result.getSession());
final RespondToAuthChallengeResult respondToAuthChallengeResult = provider
.respondToAuthChallenge(respondToAuthChallengeRequest);
log.info("MFA Login Successfully for APP MFA and the result is {} : ",
respondToAuthChallengeResult.getChallengeName());
log.info("respondToAuthChallengeResult.getAuthenticationResult()"
+ respondToAuthChallengeResult.getAuthenticationResult());
}
Articles/Questions related to AWS Cognito TOTP Software Token MFA Using Java
Create a Cognito user pool in AWS Console | Set up an Amazon Cognito user poolAWS Cognito Change User password Using Java
Cognito Confirming User Accounts using Java
AWS Cognito SignUp and SignIn Example Using Java
AWS Cognito Change User Email for Phone using Java
AWS Cognito Reset User MFA Using Java
AWS Cognito Enable SMS MFA Using Java
AWS Cognito Change User Email for Phone using Java
How to list all Amazon Cognito Users using Java
AWSCognitoIdentityProvider Method Example for Cognito User Pools API
In this article, we have seen AWS Cognito TOTP Software Token MFA Using Java. All source code in the article can be found in the GitHub repository.
0 Comments
Post a Comment