Skip to content

Commit 0720f2a

Browse files
committed
[CognitoUserPools] Add new AuthenticationDetails constructor to handle SRP before custom auth flow
1 parent 3d955db commit 0720f2a

File tree

2 files changed

+65
-22
lines changed

2 files changed

+65
-22
lines changed

aws-android-sdk-cognitoidentityprovider/src/main/java/com/amazonaws/mobileconnectors/cognitoidentityprovider/CognitoUser.java

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,11 +2383,29 @@ public void run() {
23832383
*/
23842384
private Runnable startWithCustomAuth(final AuthenticationDetails authenticationDetails,
23852385
final AuthenticationHandler callback, final boolean runInBackground) {
2386-
final InitiateAuthRequest initiateAuthRequest = initiateCustomAuthRequest(
2387-
authenticationDetails);
23882386
try {
2387+
final AuthenticationHelper authenticationHelper = new AuthenticationHelper(this.getUserPoolId());
2388+
final InitiateAuthRequest initiateAuthRequest = initiateCustomAuthRequest(
2389+
authenticationDetails,
2390+
authenticationHelper);
23892391
final InitiateAuthResult initiateAuthResult = cognitoIdentityProviderClient
23902392
.initiateAuth(initiateAuthRequest);
2393+
updateInternalUsername(initiateAuthResult.getChallengeParameters());
2394+
if (CognitoServiceConstants.CHLG_TYPE_USER_PASSWORD_VERIFIER
2395+
.equals(initiateAuthResult.getChallengeName())) {
2396+
if (authenticationDetails.getPassword() == null) {
2397+
throw new IllegalStateException("Failed to find password in " +
2398+
"authentication details to response to PASSWORD_VERIFIER challenge");
2399+
}
2400+
final RespondToAuthChallengeRequest challengeRequest = userSrpAuthRequest(
2401+
initiateAuthResult.getChallengeParameters(),
2402+
authenticationDetails.getPassword(),
2403+
initiateAuthResult.getChallengeName(),
2404+
initiateAuthResult.getSession(),
2405+
authenticationHelper
2406+
);
2407+
return respondToChallenge(challengeRequest, callback, runInBackground);
2408+
}
23912409
return handleChallenge(initiateAuthResult, authenticationDetails, callback, runInBackground);
23922410
} catch (final Exception e) {
23932411
return new Runnable() {
@@ -2477,21 +2495,13 @@ public void run() {
24772495
}
24782496
}
24792497
} else if (CognitoServiceConstants.CHLG_TYPE_USER_PASSWORD_VERIFIER.equals(challengeName)) {
2480-
if (authenticationDetails == null || authenticationDetails.getPassword() == null) {
2481-
return nextTask;
2482-
}
2483-
2484-
nextTask = new Runnable() {
2498+
return new Runnable() {
24852499
@Override
24862500
public void run() {
2487-
final RespondToAuthChallengeRequest challengeRequest = userSrpAuthRequest(
2488-
challenge.getChallengeParameters(),
2489-
authenticationDetails.getPassword(),
2490-
challenge.getChallengeName(),
2491-
challenge.getSession(),
2492-
new AuthenticationHelper(pool.getUserPoolId())
2493-
);
2494-
respondToChallenge(challengeRequest, callback, runInBackground);
2501+
callback.onFailure(new CognitoInternalErrorException(
2502+
"Authentication failed due to an internal error: " +
2503+
"PASSWORD_VERIFIER challenge encountered not at the " +
2504+
"start of authentication flow"));
24952505
}
24962506
};
24972507
} else if (CognitoServiceConstants.CHLG_TYPE_SMS_MFA.equals(challengeName)
@@ -2623,7 +2633,7 @@ public void run() {
26232633
private InitiateAuthRequest initiateUserPasswordAuthRequest(
26242634
AuthenticationDetails authenticationDetails) {
26252635

2626-
if (StringUtils.isBlank(authenticationDetails.getUserId())
2636+
if (StringUtils.isBlank(authenticationDetails.getUserId())
26272637
|| StringUtils.isBlank(authenticationDetails.getPassword())) {
26282638
throw new CognitoNotAuthorizedException("User name and password are required");
26292639
}
@@ -2768,8 +2778,8 @@ private InitiateAuthRequest initiateUserSrpAuthRequest(
27682778
* @return {@link InitiateAuthRequest}, request to start with the user SRP
27692779
* authentication.
27702780
*/
2771-
private InitiateAuthRequest initiateCustomAuthRequest(
2772-
AuthenticationDetails authenticationDetails) {
2781+
private InitiateAuthRequest initiateCustomAuthRequest(final AuthenticationDetails authenticationDetails,
2782+
final AuthenticationHelper authenticationHelper) {
27732783
final InitiateAuthRequest authRequest = new InitiateAuthRequest();
27742784
authRequest.setAuthFlow(CognitoServiceConstants.AUTH_TYPE_INIT_CUSTOM_AUTH);
27752785
authRequest.setClientId(clientId);
@@ -2784,6 +2794,9 @@ private InitiateAuthRequest initiateCustomAuthRequest(
27842794
secretHash = CognitoSecretHash.getSecretHash(authenticationDetails.getUserId(), clientId, clientSecret);
27852795
authenticationParameters.put(CognitoServiceConstants.AUTH_PARAM_SECRET_HASH, secretHash);
27862796
}
2797+
if (CognitoServiceConstants.AUTH_PARAM_SRP_A.equals(authenticationDetails.getCustomChallenge())) {
2798+
authenticationParameters.put(CognitoServiceConstants.AUTH_PARAM_SRP_A, authenticationHelper.getA().toString(16));
2799+
}
27872800
authRequest.setAuthParameters(authenticationDetails.getAuthenticationParameters());
27882801

27892802
if (authenticationDetails.getValidationData() != null
@@ -2842,7 +2855,7 @@ private InitiateAuthRequest initiateRefreshTokenAuthRequest(CognitoUserSession c
28422855
deviceKey = CognitoDeviceHelper.getDeviceKey(usernameInternal, pool.getUserPoolId(),
28432856
context);
28442857
} else {
2845-
deviceKey = CognitoDeviceHelper.getDeviceKey(currSession.getUsername(),
2858+
deviceKey = CognitoDeviceHelper.getDeviceKey(currSession.getUsername(),
28462859
pool.getUserPoolId(), context);
28472860
}
28482861
}
@@ -3096,8 +3109,8 @@ public void listDevices(int limit, String paginationToken, DevicesHandler callba
30963109

30973110
/**
30983111
* Returns the current device, if users in this pool can remember devices.
3099-
* If a deviceKey is not found with the userId, the deviceKey is searched
3100-
* with the username in cached tokens, if any.
3112+
* If a deviceKey is not found with the userId, the deviceKey is searched
3113+
* with the username in cached tokens, if any.
31013114
* @return {@link CognitoDevice} if the device is available, null otherwise.
31023115
*/
31033116
public CognitoDevice thisDevice() {
@@ -3109,7 +3122,7 @@ public CognitoDevice thisDevice() {
31093122
deviceKey = CognitoDeviceHelper.getDeviceKey(userId, pool.getUserPoolId(), context);
31103123
if (deviceKey == null) {
31113124
CognitoUserSession currSession = this.readCachedTokens();
3112-
deviceKey = CognitoDeviceHelper.getDeviceKey(currSession.getUsername(),
3125+
deviceKey = CognitoDeviceHelper.getDeviceKey(currSession.getUsername(),
31133126
this.pool.getUserPoolId(), this.context);
31143127
}
31153128
}

aws-android-sdk-cognitoidentityprovider/src/main/java/com/amazonaws/mobileconnectors/cognitoidentityprovider/continuations/AuthenticationDetails.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,32 @@ public AuthenticationDetails(String userId, String password,
5353
setValidationData(validationData);
5454
}
5555

56+
/**
57+
* Constructs a new object for custom authentication that starts with SRP protocol.
58+
* The first to challenges to be answered are SRP_A and PASSWORD_VERIFIER.
59+
*
60+
* @param userId REQUIRED: User ID, NOTE: This will over ride the current user ID
61+
* @param password REQUIRED: This will be used to answer the PASSWORD_VERIFIER challenge.
62+
* @param authenticationParameters REQUIRED: Authentication details that are used in custom
63+
* authentication process
64+
* @param validationData REQUIRED: Contains authentication parameters which are passed to
65+
* triggered pre-auth lambda trigger.
66+
*/
67+
public AuthenticationDetails(String userId, String password, Map<String, String> authenticationParameters,
68+
Map<String, String> validationData) {
69+
this.userId = userId;
70+
this.password = password;
71+
if (authenticationParameters != null) {
72+
this.authenticationType = CognitoServiceConstants.CHLG_TYPE_CUSTOM_CHALLENGE;
73+
this.authenticationParameters = authenticationParameters;
74+
setAuthenticationParameter(CognitoServiceConstants.AUTH_PARAM_USERNAME, userId);
75+
setCustomChallenge(CognitoServiceConstants.AUTH_PARAM_SRP_A);
76+
setValidationData(validationData);
77+
} else {
78+
this.authenticationType = null;
79+
}
80+
}
81+
5682
/**
5783
* Constructs a new object for custom authentication.
5884
*
@@ -156,6 +182,10 @@ public void setCustomChallenge(String customChallenge) {
156182
customChallenge);
157183
}
158184

185+
public String getCustomChallenge() {
186+
return this.authenticationParameters.get(CognitoServiceConstants.AUTH_PARAM_CHALLENGE_NAME);
187+
}
188+
159189
/**
160190
* Set the name of the authentication challenge.
161191
*

0 commit comments

Comments
 (0)