use of org.keycloak.models.OTPPolicy in project keycloak by keycloak.
the class AccountFormService method processTotpUpdate.
/**
* Update the TOTP for this account.
* <p>
* form parameters:
* <p>
* totp - otp generated by authenticator
* totpSecret - totp secret to register
*
* @return
*/
@Path("totp")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response processTotpUpdate() {
MultivaluedMap<String, String> formData = request.getDecodedFormParameters();
if (auth == null) {
return login("totp");
}
auth.require(AccountRoles.MANAGE_ACCOUNT);
account.setAttribute("mode", session.getContext().getUri().getQueryParameters().getFirst("mode"));
String action = formData.getFirst("submitAction");
if (action != null && action.equals("Cancel")) {
setReferrerOnPage();
return account.createResponse(AccountPages.TOTP);
}
csrfCheck(formData);
UserModel user = auth.getUser();
if (action != null && action.equals("Delete")) {
String credentialId = formData.getFirst("credentialId");
if (credentialId == null) {
setReferrerOnPage();
return account.setError(Status.OK, Messages.UNEXPECTED_ERROR_HANDLING_REQUEST).createResponse(AccountPages.TOTP);
}
CredentialHelper.deleteOTPCredential(session, realm, user, credentialId);
event.event(EventType.REMOVE_TOTP).client(auth.getClient()).user(auth.getUser()).success();
setReferrerOnPage();
return account.setSuccess(Messages.SUCCESS_TOTP_REMOVED).createResponse(AccountPages.TOTP);
} else {
String challengeResponse = formData.getFirst("totp");
String totpSecret = formData.getFirst("totpSecret");
String userLabel = formData.getFirst("userLabel");
OTPPolicy policy = realm.getOTPPolicy();
OTPCredentialModel credentialModel = OTPCredentialModel.createFromPolicy(realm, totpSecret, userLabel);
if (Validation.isBlank(challengeResponse)) {
setReferrerOnPage();
return account.setError(Status.OK, Messages.MISSING_TOTP).createResponse(AccountPages.TOTP);
} else if (!CredentialValidation.validOTP(challengeResponse, credentialModel, policy.getLookAheadWindow())) {
setReferrerOnPage();
return account.setError(Status.OK, Messages.INVALID_TOTP).createResponse(AccountPages.TOTP);
}
if (!CredentialHelper.createOTPCredential(session, realm, user, challengeResponse, credentialModel)) {
setReferrerOnPage();
return account.setError(Status.OK, Messages.INVALID_TOTP).createResponse(AccountPages.TOTP);
}
event.event(EventType.UPDATE_TOTP).client(auth.getClient()).user(auth.getUser()).success();
setReferrerOnPage();
return account.setSuccess(Messages.SUCCESS_TOTP).createResponse(AccountPages.TOTP);
}
}
use of org.keycloak.models.OTPPolicy in project keycloak by keycloak.
the class BasicAuthOTPAuthenticator method onAuthenticate.
@Override
protected boolean onAuthenticate(AuthenticationFlowContext context, String[] challenge) {
String username = challenge[0];
String password = challenge[1];
OTPPolicy otpPolicy = context.getRealm().getOTPPolicy();
int otpLength = otpPolicy.getDigits();
if (password.length() < otpLength) {
return false;
}
password = password.substring(0, password.length() - otpLength);
if (checkUsernameAndPassword(context, username, password)) {
String otp = challenge[1].substring(password.length(), challenge[1].length());
if (checkOtp(context, otp)) {
return true;
}
}
return false;
}
use of org.keycloak.models.OTPPolicy in project keycloak by keycloak.
the class LoginHotpTest method before.
@Before
public void before() throws MalformedURLException {
RealmRepresentation testRealm = testRealm().toRepresentation();
policy = new OTPPolicy();
policy.setAlgorithm(testRealm.getOtpPolicyAlgorithm());
policy.setDigits(testRealm.getOtpPolicyDigits());
policy.setInitialCounter(testRealm.getOtpPolicyInitialCounter());
policy.setLookAheadWindow(testRealm.getOtpPolicyLookAheadWindow());
policy.setPeriod(testRealm.getOtpPolicyLookAheadWindow());
policy.setType(testRealm.getOtpPolicyType());
otp = new HmacOTP(policy.getDigits(), policy.getAlgorithm(), policy.getLookAheadWindow());
}
use of org.keycloak.models.OTPPolicy in project keycloak by keycloak.
the class OTPCredentialProvider method isValid.
@Override
public boolean isValid(RealmModel realm, UserModel user, CredentialInput credentialInput) {
if (!(credentialInput instanceof UserCredentialModel)) {
logger.debug("Expected instance of UserCredentialModel for CredentialInput");
return false;
}
String challengeResponse = credentialInput.getChallengeResponse();
if (challengeResponse == null) {
return false;
}
if (ObjectUtil.isBlank(credentialInput.getCredentialId())) {
logger.debugf("CredentialId is null when validating credential of user %s", user.getUsername());
return false;
}
CredentialModel credential = getCredentialStore().getStoredCredentialById(realm, user, credentialInput.getCredentialId());
OTPCredentialModel otpCredentialModel = OTPCredentialModel.createFromCredentialModel(credential);
OTPSecretData secretData = otpCredentialModel.getOTPSecretData();
OTPCredentialData credentialData = otpCredentialModel.getOTPCredentialData();
OTPPolicy policy = realm.getOTPPolicy();
if (OTPCredentialModel.HOTP.equals(credentialData.getSubType())) {
HmacOTP validator = new HmacOTP(credentialData.getDigits(), credentialData.getAlgorithm(), policy.getLookAheadWindow());
int counter = validator.validateHOTP(challengeResponse, secretData.getValue(), credentialData.getCounter());
if (counter < 0) {
return false;
}
otpCredentialModel.updateCounter(counter);
getCredentialStore().updateCredential(realm, user, otpCredentialModel);
return true;
} else if (OTPCredentialModel.TOTP.equals(credentialData.getSubType())) {
TimeBasedOTP validator = new TimeBasedOTP(credentialData.getAlgorithm(), credentialData.getDigits(), credentialData.getPeriod(), policy.getLookAheadWindow());
return validator.validateTOTP(challengeResponse, secretData.getValue().getBytes(StandardCharsets.UTF_8));
}
return false;
}
Aggregations