Search in sources :

Example 6 with OTPCredentialModel

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);
    });
}
Also used : RealmModel(org.keycloak.models.RealmModel) UserModel(org.keycloak.models.UserModel) LDAPObject(org.keycloak.storage.ldap.idm.model.LDAPObject) OTPCredentialModel(org.keycloak.models.credential.OTPCredentialModel)

Example 7 with OTPCredentialModel

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;
}
Also used : OTPSecretData(org.keycloak.models.credential.dto.OTPSecretData) HmacOTP(org.keycloak.models.utils.HmacOTP) UserCredentialModel(org.keycloak.models.UserCredentialModel) OTPCredentialModel(org.keycloak.models.credential.OTPCredentialModel) TimeBasedOTP(org.keycloak.models.utils.TimeBasedOTP) OTPCredentialData(org.keycloak.models.credential.dto.OTPCredentialData) OTPCredentialModel(org.keycloak.models.credential.OTPCredentialModel) OTPPolicy(org.keycloak.models.OTPPolicy) UserCredentialModel(org.keycloak.models.UserCredentialModel)

Example 8 with OTPCredentialModel

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);
    }
}
Also used : UserModel(org.keycloak.models.UserModel) OTPCredentialModel(org.keycloak.models.credential.OTPCredentialModel) OTPPolicy(org.keycloak.models.OTPPolicy) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes)

Example 9 with OTPCredentialModel

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();
}
Also used : EventBuilder(org.keycloak.events.EventBuilder) OTPCredentialModel(org.keycloak.models.credential.OTPCredentialModel) OTPPolicy(org.keycloak.models.OTPPolicy)

Aggregations

OTPCredentialModel (org.keycloak.models.credential.OTPCredentialModel)9 OTPPolicy (org.keycloak.models.OTPPolicy)4 UserCredentialModel (org.keycloak.models.UserCredentialModel)4 Response (javax.ws.rs.core.Response)3 CredentialModel (org.keycloak.credential.CredentialModel)3 UserModel (org.keycloak.models.UserModel)3 CredentialProvider (org.keycloak.credential.CredentialProvider)2 EventBuilder (org.keycloak.events.EventBuilder)2 Consumes (javax.ws.rs.Consumes)1 POST (javax.ws.rs.POST)1 Path (javax.ws.rs.Path)1 Test (org.junit.Test)1 OTPCredentialProvider (org.keycloak.credential.OTPCredentialProvider)1 RealmModel (org.keycloak.models.RealmModel)1 PasswordCredentialModel (org.keycloak.models.credential.PasswordCredentialModel)1 OTPCredentialData (org.keycloak.models.credential.dto.OTPCredentialData)1 OTPSecretData (org.keycloak.models.credential.dto.OTPSecretData)1 FormMessage (org.keycloak.models.utils.FormMessage)1 HmacOTP (org.keycloak.models.utils.HmacOTP)1 TimeBasedOTP (org.keycloak.models.utils.TimeBasedOTP)1