use of org.keycloak.models.credential.OTPCredentialModel in project keycloak by keycloak.
the class LDAPUserMultipleCredentialTest method afterImportTestRealm.
@Override
protected void afterImportTestRealm() {
getTestingClient().server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
// Delete all LDAP users
LDAPTestUtils.removeAllLDAPUsers(ctx.getLdapProvider(), appRealm);
// Add some new LDAP users for testing
LDAPObject user1 = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "test-user", "John", "Doe", "test-user@something.org", "some street", "00000");
LDAPTestUtils.updateLDAPPassword(ctx.getLdapProvider(), user1, "some-password");
LDAPObject user2 = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "test-user-with-otp", "John", "Doe", "test-user-with-otp@something.org", "some street", "00000");
LDAPTestUtils.updateLDAPPassword(ctx.getLdapProvider(), user2, "some-other-password");
UserModel userWithOtp = session.users().getUserByUsername(appRealm, "test-user-with-otp");
OTPCredentialModel otpCredential = OTPCredentialModel.createHOTP("DJmQfC73VGFhw7D4QJ8A", 6, 0, "HmacSHA1");
session.userCredentialManager().createCredential(appRealm, userWithOtp, otpCredential);
});
}
use of org.keycloak.models.credential.OTPCredentialModel 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;
}
use of org.keycloak.models.credential.OTPCredentialModel 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.credential.OTPCredentialModel in project keycloak by keycloak.
the class ConsoleUpdateTotp method processAction.
@Override
public void processAction(RequiredActionContext context) {
EventBuilder event = context.getEvent();
event.event(EventType.UPDATE_TOTP);
MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
String challengeResponse = formData.getFirst("totp");
String totpSecret = context.getAuthenticationSession().getAuthNote("totpSecret");
String userLabel = formData.getFirst("userLabel");
OTPPolicy policy = context.getRealm().getOTPPolicy();
OTPCredentialModel credentialModel = OTPCredentialModel.createFromPolicy(context.getRealm(), totpSecret, userLabel);
if (Validation.isBlank(challengeResponse)) {
context.challenge(challenge(context).message(Messages.MISSING_TOTP));
return;
} else if (!CredentialValidation.validOTP(challengeResponse, credentialModel, policy.getLookAheadWindow())) {
context.challenge(challenge(context).message(Messages.INVALID_TOTP));
return;
}
if (!CredentialHelper.createOTPCredential(context.getSession(), context.getRealm(), context.getUser(), challengeResponse, credentialModel)) {
context.challenge(challenge(context).message(Messages.INVALID_TOTP));
return;
}
context.getAuthenticationSession().removeAuthNote("totpSecret");
context.success();
}
Aggregations