use of com.amazonaws.mobileconnectors.cognitoidentityprovider.exceptions.CognitoInternalErrorException 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.exceptions.CognitoInternalErrorException in project aws-sdk-android by aws-amplify.
the class CognitoUser method deviceSrpAuthRequest.
/**
* Creates request for device SRP verification.
*
* @param clientMetadata A map of custom key-value pairs that is passed to the lambda function for
* custom workflow.
* @param challenge REQUIRED: {@link RespondToAuthChallengeResult} contains
* next challenge.
* @param deviceSecret REQUIRED: Device secret verifier.
* @param authenticationHelper REQUIRED: Internal helper class for SRP
* calculations.
* @param deviceGroupKey the device group key
* @return {@link RespondToAuthChallengeRequest}.
*/
public RespondToAuthChallengeRequest deviceSrpAuthRequest(final Map<String, String> clientMetadata, RespondToAuthChallengeResult challenge, String deviceSecret, String deviceGroupKey, AuthenticationHelper authenticationHelper) {
this.usernameInternal = challenge.getChallengeParameters().get(CognitoServiceConstants.CHLG_PARAM_USERNAME);
final BigInteger srpB = new BigInteger(challenge.getChallengeParameters().get("SRP_B"), 16);
if (srpB.mod(AuthenticationHelper.N).equals(BigInteger.ZERO)) {
throw new CognitoInternalErrorException("SRP error, B cannot be zero");
}
final BigInteger salt = new BigInteger(challenge.getChallengeParameters().get("SALT"), 16);
final byte[] key = authenticationHelper.getPasswordAuthenticationKey(deviceKey, deviceSecret, srpB, salt);
final Date timestamp = new Date();
byte[] hmac;
String dateString;
try {
final Mac mac = Mac.getInstance("HmacSHA256");
final SecretKeySpec keySpec = new SecretKeySpec(key, "HmacSHA256");
mac.init(keySpec);
mac.update(deviceGroupKey.getBytes(StringUtils.UTF8));
mac.update(deviceKey.getBytes(StringUtils.UTF8));
final byte[] secretBlock = Base64.decode(challenge.getChallengeParameters().get(CognitoServiceConstants.CHLG_PARAM_SECRET_BLOCK));
mac.update(secretBlock);
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy", Locale.US);
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
dateString = simpleDateFormat.format(timestamp);
final byte[] dateBytes = dateString.getBytes(StringUtils.UTF8);
hmac = mac.doFinal(dateBytes);
} catch (final Exception e) {
throw new CognitoInternalErrorException("SRP error", e);
}
secretHash = CognitoSecretHash.getSecretHash(usernameInternal, clientId, clientSecret);
final Map<String, String> srpAuthResponses = new HashMap<String, String>();
srpAuthResponses.put(CognitoServiceConstants.CHLG_RESP_PASSWORD_CLAIM_SECRET_BLOCK, challenge.getChallengeParameters().get(CognitoServiceConstants.CHLG_PARAM_SECRET_BLOCK));
srpAuthResponses.put(CognitoServiceConstants.CHLG_RESP_PASSWORD_CLAIM_SIGNATURE, new String(Base64.encode(hmac), StringUtils.UTF8));
srpAuthResponses.put(CognitoServiceConstants.CHLG_RESP_TIMESTAMP, dateString);
srpAuthResponses.put(CognitoServiceConstants.CHLG_RESP_USERNAME, usernameInternal);
srpAuthResponses.put(CognitoServiceConstants.CHLG_RESP_DEVICE_KEY, deviceKey);
srpAuthResponses.put(CognitoServiceConstants.CHLG_RESP_SECRET_HASH, secretHash);
final RespondToAuthChallengeRequest authChallengeRequest = new RespondToAuthChallengeRequest();
authChallengeRequest.setChallengeName(challenge.getChallengeName());
authChallengeRequest.setClientId(clientId);
authChallengeRequest.setSession(challenge.getSession());
authChallengeRequest.setChallengeResponses(srpAuthResponses);
authChallengeRequest.setUserContextData(getUserContextData());
authChallengeRequest.setClientMetadata(clientMetadata);
return authChallengeRequest;
}
use of com.amazonaws.mobileconnectors.cognitoidentityprovider.exceptions.CognitoInternalErrorException in project aws-sdk-android by aws-amplify.
the class CognitoUser method getCachedSession.
/**
* Call this method for valid, cached tokens for this user.
*
* @return Valid, cached tokens {@link CognitoUserSession}. {@code null}
* otherwise.
*/
protected CognitoUserSession getCachedSession() {
synchronized (GET_CACHED_SESSION_LOCK) {
if (userId == null) {
throw new CognitoNotAuthorizedException("User-ID is null");
}
if (cipSession != null) {
if (cipSession.isValidForThreshold()) {
cacheLastAuthUser();
return cipSession;
}
}
final CognitoUserSession cognitoUserSessionFromStore = readCachedTokens();
if (cognitoUserSessionFromStore.isValidForThreshold()) {
cipSession = cognitoUserSessionFromStore;
cacheLastAuthUser();
return cipSession;
}
if (cognitoUserSessionFromStore.getRefreshToken() != null) {
try {
cipSession = refreshSession(cognitoUserSessionFromStore);
cacheTokens(cipSession);
return cipSession;
} catch (final NotAuthorizedException nae) {
clearCachedTokens();
throw new CognitoNotAuthorizedException("User is not authenticated", nae);
} catch (final UserNotFoundException unfe) {
clearCachedTokens();
throw new CognitoNotAuthorizedException("User does not exist", unfe);
} catch (final Exception e) {
throw new CognitoInternalErrorException("Failed to authenticate user", e);
}
}
throw new CognitoNotAuthorizedException("User is not authenticated");
}
}
use of com.amazonaws.mobileconnectors.cognitoidentityprovider.exceptions.CognitoInternalErrorException in project aws-sdk-android by aws-amplify.
the class CognitoUser method verifySoftwareToken.
/**
* Verify the Time-based One-time Password based MFA tpo complete registration, in current thread.
* @param sessionToken Optional: If a session token has to be used to register the MFA.
* @param totpCode Required: The TOTP code.
* @param friendlyName Required: Friendly name to be associated with this MFA.
* @param callback Required: Callback handler {@link VerifyMfaContinuation}.
*/
public void verifySoftwareToken(final String sessionToken, final String totpCode, final String friendlyName, final RegisterMfaHandler callback) {
if (callback == null) {
throw new CognitoParameterInvalidException("callback is null");
}
final CognitoUser user = this;
boolean useSessionToken;
try {
final CognitoUserSession cognitoTokens = user.getCachedSession();
VerifySoftwareTokenResult result;
if (!StringUtils.isBlank(sessionToken)) {
result = verifyTotpAssociationWithSession(sessionToken, totpCode, friendlyName);
useSessionToken = true;
} else {
result = verifyTotpAssociationWithTokens(cognitoTokens, totpCode, friendlyName);
useSessionToken = false;
}
final String newSessionToken = result.getSession();
if (VerifySoftwareTokenResponseType.ERROR.equals(result.getStatus())) {
throw new CognitoInternalErrorException("verification failed");
}
if (useSessionToken) {
callback.onSuccess(newSessionToken);
} else {
callback.onSuccess(null);
}
} catch (Exception e) {
callback.onFailure(e);
}
}
use of com.amazonaws.mobileconnectors.cognitoidentityprovider.exceptions.CognitoInternalErrorException in project aws-sdk-android by aws-amplify.
the class CognitoIdToken method getIssuedAt.
/**
* Returns "issued at" claim of this id token
*
* @return issue at claim as {@link java.util.Date} in UTC.
*/
public Date getIssuedAt() {
try {
final String claim = CognitoJWTParser.getClaim(super.getToken(), "iat");
if (claim == null) {
return null;
}
final long epocTimeSec = Long.parseLong(claim);
final long epocTimeMilliSec = epocTimeSec * SECS;
return new Date(epocTimeMilliSec);
} catch (final Exception e) {
throw new CognitoInternalErrorException(e.getMessage(), e);
}
}
Aggregations