Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle errors in the TOTP flow #176

Merged
merged 4 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException;
import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser;
import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatorData;
import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatorMessage;
import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatorParamMetadata;
import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants;
import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils;
Expand Down Expand Up @@ -98,6 +99,8 @@ public class TOTPAuthenticator extends AbstractApplicationAuthenticator
private static final long serialVersionUID = 2009231028659744926L;
private static final Log log = LogFactory.getLog(TOTPAuthenticator.class);
private static final String IS_API_BASED = "IS_API_BASED";
private static final String AUTHENTICATOR_MESSAGE = "authenticatorMessage";
private static final String LOCKED_REASON = "lockedReason";

/**
* Check whether token or action are in request.
Expand Down Expand Up @@ -304,6 +307,12 @@ protected void initiateAuthenticationRequest(HttpServletRequest request,
String.valueOf(Math.round((double) timeToUnlock / 1000 / 60)));
}
errorParam = buildErrorParamString(paramMap);
Map<String, String> messageContext = getMessageContext(LOCKED_REASON, String.valueOf(reason));
String message =
String.format("Authentication failed since authenticated user: %s, account is locked.",
getUserStoreAppendedName(username));
AuthenticatorMessage authenticatorMessage = getAuthenticatorMessage(message, messageContext);
setAuthenticatorMessageToContext(authenticatorMessage, context);
}
}
}
Expand Down Expand Up @@ -451,6 +460,13 @@ private long getUnlockTimeInMilliSeconds(AuthenticatedUser authenticatedUser) th
return Long.parseLong(claimValues.get(TOTPAuthenticatorConstants.ACCOUNT_UNLOCK_TIME_CLAIM));
}

private static Map<String, String> getMessageContext(String key, String value) {

Map <String,String> messageContext = new HashMap<>();
messageContext.put(key, value);
return messageContext;
}

private String buildTOTPLoginPageURL(AuthenticationContext context, String username, String retryParam,
String errorParam, String multiOptionURI)
throws AuthenticationFailedException, URISyntaxException, URLBuilderException {
Expand Down Expand Up @@ -671,11 +687,23 @@ private void validateAccountLockStatusForLocalUser(AuthenticationContext context
}
IdentityErrorMsgContext customErrorMessageContext = new IdentityErrorMsgContext(
UserCoreConstants.ErrorCode.USER_IS_LOCKED + ":" + accountLockedReason);
String message =
String.format("Authentication failed since authenticated user: %s, account is locked.",
getUserStoreAppendedName(username));
AuthenticatorMessage authenticatorMessage = getAuthenticatorMessage
(message, null);
setAuthenticatorMessageToContext(authenticatorMessage, context);
IdentityUtil.setIdentityErrorMsg(customErrorMessageContext);
throw new AuthenticationFailedException(errorMessage);
}
}

private static void setAuthenticatorMessageToContext(AuthenticatorMessage errorMessage,
AuthenticationContext context) {

context.setProperty(AUTHENTICATOR_MESSAGE, errorMessage);
}

/**
* Check whether status of retrying authentication.
*
Expand Down Expand Up @@ -1018,6 +1046,8 @@ private void handleTotpVerificationFail(AuthenticationContext context) throws Au
setUserClaimValues(authenticatedUser, updatedClaims);
String errorMessage = String.format("User account: %s is locked.", (LoggerUtils.isLogMaskingEnable ?
LoggerUtils.getMaskedContent(authenticatedUser.getUserName()) : authenticatedUser.getUserName()));
AuthenticatorMessage authenticatorMessage = getAuthenticatorMessage(errorMessage, null);
setAuthenticatorMessageToContext(authenticatorMessage, context);
IdentityErrorMsgContext customErrorMessageContext = new IdentityErrorMsgContext(
UserCoreConstants.ErrorCode.USER_IS_LOCKED + ":" +
TOTPAuthenticatorConstants.MAX_TOTP_ATTEMPTS_EXCEEDED);
Expand All @@ -1030,6 +1060,14 @@ private void handleTotpVerificationFail(AuthenticationContext context) throws Au
}
}

private static AuthenticatorMessage getAuthenticatorMessage(String errorMessage, Map<String, String> context) {

return new AuthenticatorMessage(FrameworkConstants.AuthenticatorMessageType.ERROR,
UserCoreConstants.ErrorCode.USER_IS_LOCKED,
errorMessage,
context);
}

private void resetTotpFailedAttempts(AuthenticationContext context) throws AuthenticationFailedException {

/*
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@
<carbon.commons.version>4.8.7</carbon.commons.version>
<carbon.commons.imp.pkg.version>[4.4.0, 5.0.0)</carbon.commons.imp.pkg.version>
<!--Carbon identity version-->
<carbon.identity.framework.version>5.25.491</carbon.identity.framework.version>
<carbon.identity.framework.version>5.25.503</carbon.identity.framework.version>

<org.wso2.carbon.identity.organization.management.core.version>1.0.0
</org.wso2.carbon.identity.organization.management.core.version>
Expand Down
Loading