use of com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.ChallengeContinuation in project aws-sdk-android by aws-amplify.
the class OAuth2Utils method _signIn.
private Runnable _signIn(final String username, final String password, final Map<String, String> validationData, final Map<String, String> clientMetadata, final AuthFlowType authFlowType, final Callback<SignInResult> callback) {
this.signInCallback = callback;
signInState = null;
mStore.set(SIGN_IN_MODE, SignInMode.SIGN_IN.toString());
return new Runnable() {
@Override
public void run() {
try {
userpool.getUser(username).getSession(clientMetadata, new AuthenticationHandler() {
@Override
public void onSuccess(CognitoUserSession userSession, CognitoDevice newDevice) {
try {
mCognitoUserSession = userSession;
signInState = SignInState.DONE;
} catch (Exception e) {
signInCallback.onError(e);
signInCallback = null;
}
try {
if (isFederationEnabled()) {
federatedSignInWithoutAssigningState(userpoolsLoginKey, mCognitoUserSession.getIdToken().getJWTToken());
}
releaseSignInWait();
} catch (Exception e) {
Log.w(TAG, "Failed to federate tokens during sign-in", e);
} finally {
setUserState(new UserStateDetails(UserState.SIGNED_IN, getSignInDetailsMap()));
}
signInCallback.onResult(SignInResult.DONE);
}
@Override
public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String userId) {
Log.d(TAG, "Sending password.");
final HashMap<String, String> authParameters = new HashMap<>();
// Check if the auth flow type setting is in the configuration.
boolean authFlowTypeInConfig = awsConfiguration.optJsonObject(AUTH_KEY) != null && awsConfiguration.optJsonObject(AUTH_KEY).has("authenticationFlowType");
try {
String resolvedAuthFlowType = authFlowType != null ? authFlowType.name() : null;
if (resolvedAuthFlowType == null && authFlowTypeInConfig) {
resolvedAuthFlowType = awsConfiguration.optJsonObject(AUTH_KEY).getString("authenticationFlowType");
}
if (resolvedAuthFlowType != null && AUTH_TYPE_INIT_CUSTOM_AUTH.equals(resolvedAuthFlowType)) {
// use one of the below constructors depending on what's passed in.
if (password != null) {
authenticationContinuation.setAuthenticationDetails(new AuthenticationDetails(username, password, authParameters, validationData));
} else {
authenticationContinuation.setAuthenticationDetails(new AuthenticationDetails(username, authParameters, validationData));
}
} else if (resolvedAuthFlowType != null && AUTH_TYPE_INIT_USER_PASSWORD.equals(resolvedAuthFlowType)) {
// If there's a value in the config and it's USER_PASSWORD_AUTH, set the auth type (challenge name)
// to be USER_PASSWORD.
AuthenticationDetails authenticationDetails = new AuthenticationDetails(username, password, validationData);
authenticationDetails.setAuthenticationType(CHLG_TYPE_USER_PASSWORD);
authenticationContinuation.setAuthenticationDetails(authenticationDetails);
} else {
// Otherwise, auth flow is USER_SRP_AUTH and the auth type (challenge name)
// will default to PASSWORD_VERIFIER.
Log.d(TAG, "Using USER_SRP_AUTH for flow type.");
authenticationContinuation.setAuthenticationDetails(new AuthenticationDetails(username, password, validationData));
}
} catch (JSONException exception) {
Log.w(TAG, "Exception while attempting to read authenticationFlowType from config.", exception);
}
authenticationContinuation.continueTask();
}
@Override
public void getMFACode(MultiFactorAuthenticationContinuation continuation) {
signInMfaContinuation = continuation;
CognitoUserCodeDeliveryDetails parameters = continuation.getParameters();
signInState = SignInState.SMS_MFA;
signInCallback.onResult(new SignInResult(SignInState.SMS_MFA, new UserCodeDeliveryDetails(parameters.getDestination(), parameters.getDeliveryMedium(), parameters.getAttributeName())));
}
@Override
public void authenticationChallenge(ChallengeContinuation continuation) {
try {
signInState = SignInState.valueOf(continuation.getChallengeName());
signInChallengeContinuation = continuation;
signInCallback.onResult(new SignInResult(signInState, continuation.getParameters()));
} catch (IllegalArgumentException e) {
signInCallback.onError(e);
}
}
@Override
public void onFailure(Exception exception) {
signInCallback.onError(exception);
}
});
} catch (Exception e) {
callback.onError(e);
}
}
};
}
use of com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.ChallengeContinuation in project aws-sdk-android by aws-amplify.
the class AWSMobileClientTest method testRevokeTokenWithSignedOutUser.
@Test
public void testRevokeTokenWithSignedOutUser() throws Exception {
auth.signIn(username, PASSWORD, null);
assertTrue("isSignedIn is true", auth.isSignedIn());
final CountDownLatch revokeTokenLatch = new CountDownLatch(1);
final CognitoUser user = userPool.getCurrentUser();
user.getSession(new AuthenticationHandler() {
@Override
public void onSuccess(CognitoUserSession userSession, CognitoDevice newDevice) {
revokeTokenLatch.countDown();
}
@Override
public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String userId) {
}
@Override
public void getMFACode(MultiFactorAuthenticationContinuation continuation) {
}
@Override
public void authenticationChallenge(ChallengeContinuation continuation) {
}
@Override
public void onFailure(Exception exception) {
exception.printStackTrace();
fail("Sign in failed.");
}
});
revokeTokenLatch.await(5, TimeUnit.SECONDS);
auth.signOut();
assertFalse("isSignedIn is false", auth.isSignedIn());
try {
user.revokeTokens();
} catch (Exception e) {
assertTrue(e instanceof InvalidParameterException);
}
}
use of com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.ChallengeContinuation in project aws-sdk-android by aws-amplify.
the class CognitoUser method initiateUserAuthentication.
/**
* Note: Please use {@link #getSession(Map, AuthenticationHandler)} or
* {@link #getSessionInBackground(AuthenticationHandler)} instead.
*
* Initiates user authentication through the generic auth flow (also called
* as Enhanced or Custom authentication). This is the first step in user
* authentication. The response to this step from the service will contain
* information about the next step in the authentication process.
*
* @param clientMetadata A map of custom key-value pairs that is passed to the lambda function for
* custom workflow.
* @param authenticationDetails REQUIRED: Contains details about the user
* authentication.
* @param runInBackground flag indicating if the operation has to run in
* background
* @param callback REQUIRED: {@link AuthenticationHandler} callback.
* @return {@link Runnable} for the next step in user authentication.
*/
public Runnable initiateUserAuthentication(final Map<String, String> clientMetadata, final AuthenticationDetails authenticationDetails, final AuthenticationHandler callback, final boolean runInBackground) {
final AuthenticationHandler internalCallback = new AuthenticationHandler() {
@Override
public void onSuccess(final CognitoUserSession userSession, final CognitoDevice newDevice) {
if (runInBackground) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
callback.onSuccess(userSession, newDevice);
}
});
} else {
callback.onSuccess(userSession, newDevice);
}
}
@Override
public void getAuthenticationDetails(final AuthenticationContinuation authenticationContinuation, final String userId) {
if (runInBackground) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
callback.getAuthenticationDetails(authenticationContinuation, userId);
}
});
} else {
callback.getAuthenticationDetails(authenticationContinuation, userId);
}
}
@Override
public void getMFACode(final MultiFactorAuthenticationContinuation continuation) {
if (runInBackground) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
callback.getMFACode(continuation);
}
});
} else {
callback.getMFACode(continuation);
}
}
@Override
public void authenticationChallenge(final ChallengeContinuation continuation) {
if (runInBackground) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
callback.authenticationChallenge(continuation);
}
});
} else {
callback.authenticationChallenge(continuation);
}
}
@Override
public void onFailure(final Exception exception) {
if (runInBackground) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
callback.onFailure(exception);
}
});
} else {
callback.onFailure(exception);
}
}
};
final Runnable task = _initiateUserAuthentication(clientMetadata, authenticationDetails, internalCallback, runInBackground);
if (runInBackground) {
return new Runnable() {
@Override
public void run() {
new Thread(new Runnable() {
@Override
public void run() {
task.run();
}
}).start();
}
};
} else {
return task;
}
}
use of com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.ChallengeContinuation in project aws-sdk-android by aws-amplify.
the class CognitoUser method handleChallenge.
/**
* Find the next step from the challenge. This is an important step in the
* generic authentication flow. After the responding to a challenge, the
* results are analyzed here to determine the next step in the
* authentication process. Like all other methods in this SDK, this is
* designed to work with Continuation objects. This method returns a
* {@link Runnable} with the code to be executed, for the next step, to the
* invoking Continuation. The possible steps are 1) Authentication was
* successful and we have the tokens, in this case we call
* {@code onSuccess()} to return the tokens. 2) User password is required,
* an AuthenticationContinuation is created. 3) MFA validation is required,
* a MultiFactorAuthenticationContinuation object is created. 4) Other
* generic challenge, the challenge details are passed to the user.
*
* @param challenge REQUIRED: Current challenge details,
* {@link RespondToAuthChallengeResult}.
* @param authenticationDetails OPTIONAL: This is used in the PASSWORD_VERIFIER challenge
* @param callback REQUIRED: {@link AuthenticationDetails} callback.
* @param runInBackground REQUIRED: Boolean to indicate the current
* threading.
* @return {@link Runnable} for the next step in user authentication.
*/
private Runnable handleChallenge(final Map<String, String> clientMetadata, final RespondToAuthChallengeResult challenge, final AuthenticationDetails authenticationDetails, final AuthenticationHandler callback, final boolean runInBackground) {
Runnable nextTask;
final CognitoUser cognitoUser = this;
nextTask = new Runnable() {
@Override
public void run() {
callback.onFailure(new CognitoInternalErrorException("Authentication failed due to an internal error"));
}
};
if (challenge == null) {
return nextTask;
}
updateInternalUsername(challenge.getChallengeParameters());
final String challengeName = challenge.getChallengeName();
if (challengeName == null) {
final CognitoUserSession cognitoUserSession = getCognitoUserSession(challenge.getAuthenticationResult());
cacheTokens(cognitoUserSession);
final NewDeviceMetadataType newDeviceMetadata = challenge.getAuthenticationResult().getNewDeviceMetadata();
if (newDeviceMetadata == null) {
nextTask = new Runnable() {
@Override
public void run() {
callback.onSuccess(cognitoUserSession, null);
}
};
} else {
final ConfirmDeviceResult confirmDeviceResult = confirmDevice(newDeviceMetadata);
if (confirmDeviceResult != null && confirmDeviceResult.isUserConfirmationNecessary()) {
final CognitoDevice newDevice = new CognitoDevice(newDeviceMetadata.getDeviceKey(), null, null, null, null, cognitoUser, context);
nextTask = new Runnable() {
@Override
public void run() {
callback.onSuccess(cognitoUserSession, newDevice);
}
};
} else {
nextTask = new Runnable() {
@Override
public void run() {
callback.onSuccess(cognitoUserSession, null);
}
};
}
}
} else if (CognitoServiceConstants.CHLG_TYPE_USER_PASSWORD_VERIFIER.equals(challengeName)) {
return new Runnable() {
@Override
public void run() {
callback.onFailure(new CognitoInternalErrorException("Authentication failed due to an internal error: " + "PASSWORD_VERIFIER challenge encountered not at the " + "start of authentication flow"));
}
};
} else if (CognitoServiceConstants.CHLG_TYPE_SMS_MFA.equals(challengeName) || CognitoServiceConstants.CHLG_TYPE_SOFTWARE_TOKEN_MFA.equals(challengeName)) {
final MultiFactorAuthenticationContinuation multiFactorAuthenticationContinuation = new MultiFactorAuthenticationContinuation(cognitoUser, context, challenge, runInBackground, callback);
multiFactorAuthenticationContinuation.setClientMetaData(clientMetadata);
nextTask = new Runnable() {
@Override
public void run() {
callback.getMFACode(multiFactorAuthenticationContinuation);
}
};
} else if (CognitoServiceConstants.CHLG_TYPE_SELECT_MFA_TYPE.equals(challengeName)) {
final ChooseMfaContinuation continuation = new ChooseMfaContinuation(cognitoUser, context, usernameInternal, clientId, secretHash, challenge, runInBackground, callback);
nextTask = new Runnable() {
@Override
public void run() {
callback.authenticationChallenge(continuation);
}
};
} else if (CognitoServiceConstants.CHLG_TYPE_MFA_SETUP.equals(challengeName)) {
final RegisterMfaContinuation continuation = new RegisterMfaContinuation(cognitoUser, context, usernameInternal, clientId, secretHash, challenge, runInBackground, callback);
nextTask = new Runnable() {
@Override
public void run() {
callback.authenticationChallenge(continuation);
}
};
} else if (CognitoServiceConstants.CHLG_TYPE_DEVICE_SRP_AUTH.equals(challengeName)) {
nextTask = deviceSrpAuthentication(clientMetadata, challenge, callback, runInBackground);
} else if (CognitoServiceConstants.CHLG_TYPE_NEW_PASSWORD_REQUIRED.equals(challengeName)) {
final NewPasswordContinuation newPasswordContinuation = new NewPasswordContinuation(cognitoUser, context, usernameInternal, clientId, CognitoSecretHash.getSecretHash(usernameInternal, clientId, clientSecret), challenge, runInBackground, callback);
nextTask = new Runnable() {
@Override
public void run() {
callback.authenticationChallenge(newPasswordContinuation);
}
};
} else {
final ChallengeContinuation challengeContinuation = new ChallengeContinuation(cognitoUser, context, usernameInternal, clientId, CognitoSecretHash.getSecretHash(usernameInternal, clientId, clientSecret), challenge, runInBackground, callback);
challengeContinuation.setClientMetaData(clientMetadata);
nextTask = new Runnable() {
@Override
public void run() {
callback.authenticationChallenge(challengeContinuation);
}
};
}
return nextTask;
}
use of com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.ChallengeContinuation in project aws-sdk-android by aws-amplify.
the class CognitoUserIntegrationTest method testCustomAuth.
@Test
public void testCustomAuth() {
final CountDownLatch signInLatch = new CountDownLatch(1);
final ArrayList<CognitoUserSession> userSessions = new ArrayList();
AuthenticationHandler authenticationHandler = new AuthenticationHandler() {
@Override
public void onSuccess(CognitoUserSession userSession, CognitoDevice newDevice) {
userSessions.add(userSession);
signInLatch.countDown();
}
@Override
public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String userId) {
final HashMap<String, String> authParameters = new HashMap<>();
// This is a passwordless flow, hance passing a dummy password.
AuthenticationDetails authenticationDetails = new AuthenticationDetails(customAuthUsername, "", authParameters, null);
authenticationContinuation.setAuthenticationDetails(authenticationDetails);
authenticationContinuation.continueTask();
}
@Override
public void getMFACode(MultiFactorAuthenticationContinuation continuation) {
fail("Tests are not configured to work with MFA. " + "Either create a CognitoUserPool without MFA or update the test.");
signInLatch.countDown();
}
@Override
public void authenticationChallenge(ChallengeContinuation continuation) {
Log.d(TAG, "Yo, Authentication Chanllenge is called Passwordless");
continuation.setChallengeResponse(CognitoServiceConstants.CHLG_RESP_ANSWER, "1133");
continuation.continueTask();
}
@Override
public void onFailure(Exception exception) {
fail("Error while signing-in. " + exception.getLocalizedMessage());
signInLatch.countDown();
}
};
cognitoUserPool.getUser(customAuthUsername).getSessionInBackground(authenticationHandler);
try {
signInLatch.await(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
assertEquals(1, userSessions.size());
// Verify that the sign-in was successful
verifyCognitoUserSessionForSignedInUser(userSessions.get(0));
}
Aggregations