Search in sources :

Example 1 with TimeBasedOTP

use of org.keycloak.models.utils.TimeBasedOTP in project keycloak by keycloak.

the class TotpTest method testTotp.

@Test
public void testTotp() {
    TimeBasedOTP totp = new TimeBasedOTP("HmacSHA1", 8, 30, 1);
    String secret = "dSdmuHLQhkm54oIm0A0S";
    String otp = totp.generateTOTP(secret);
    Assert.assertTrue(totp.validateTOTP(otp, secret.getBytes(StandardCharsets.UTF_8)));
}
Also used : TimeBasedOTP(org.keycloak.models.utils.TimeBasedOTP) Test(org.junit.Test)

Example 2 with TimeBasedOTP

use of org.keycloak.models.utils.TimeBasedOTP in project keycloak by keycloak.

the class BackwardsCompatibilityUserStorage method isValid.

@Override
public boolean isValid(RealmModel realm, UserModel user, CredentialInput input) {
    MyUser myUser = users.get(translateUserName(user.getUsername()));
    if (myUser == null)
        return false;
    if (input.getType().equals(UserCredentialModel.PASSWORD)) {
        if (!(input instanceof PasswordUserCredentialModel))
            return false;
        CredentialModel hashedPassword = myUser.hashedPassword;
        if (hashedPassword == null) {
            log.warnf("Password not set for user %s", user.getUsername());
            return false;
        }
        PasswordUserCredentialModel userCredentialModel = (PasswordUserCredentialModel) input;
        // Those are not supposed to be set when calling this method in Keycloak 4.8.3 for password credential
        assertNull(userCredentialModel.getDevice());
        assertNull(userCredentialModel.getAlgorithm());
        PasswordPolicy policy = session.getContext().getRealm().getPasswordPolicy();
        PasswordHashProvider hashProvider = getHashProvider(policy);
        String rawPassword = userCredentialModel.getValue();
        // Compatibility with 4.8.3 - using "legacy" signature of this method
        return hashProvider.verify(rawPassword, hashedPassword);
    } else if (isOTPType(input.getType())) {
        UserCredentialModel otpCredential = (UserCredentialModel) input;
        // Special hardcoded OTP, which is always considered valid
        if ("123456".equals(otpCredential.getValue())) {
            return true;
        }
        CredentialModel storedOTPCredential = myUser.otp;
        if (storedOTPCredential == null) {
            log.warnf("Not found credential for the user %s", user.getUsername());
            return false;
        }
        TimeBasedOTP validator = new TimeBasedOTP(storedOTPCredential.getAlgorithm(), storedOTPCredential.getDigits(), storedOTPCredential.getPeriod(), realm.getOTPPolicy().getLookAheadWindow());
        return validator.validateTOTP(otpCredential.getValue(), storedOTPCredential.getValue().getBytes());
    } else {
        log.infof("Not supported to validate credential of type '%s' for user '%s'", input.getType(), user.getUsername());
        return false;
    }
}
Also used : PasswordUserCredentialModel(org.keycloak.models.credential.PasswordUserCredentialModel) PasswordUserCredentialModel(org.keycloak.models.credential.PasswordUserCredentialModel) UserCredentialModel(org.keycloak.models.UserCredentialModel) CredentialModel(org.keycloak.credential.CredentialModel) TimeBasedOTP(org.keycloak.models.utils.TimeBasedOTP) PasswordPolicy(org.keycloak.models.PasswordPolicy) PasswordUserCredentialModel(org.keycloak.models.credential.PasswordUserCredentialModel) UserCredentialModel(org.keycloak.models.UserCredentialModel) PasswordHashProvider(org.keycloak.credential.hash.PasswordHashProvider)

Example 3 with TimeBasedOTP

use of org.keycloak.models.utils.TimeBasedOTP in project keycloak by keycloak.

the class RequiredActionPriorityTest method setupTotpAfterUpdatePassword.

@Test
public void setupTotpAfterUpdatePassword() {
    String testUserId = ApiUtil.findUserByUsername(testRealm(), "test-user@localhost").getId();
    setRequiredActionEnabled("test", testUserId, RequiredAction.CONFIGURE_TOTP.name(), true);
    setRequiredActionEnabled("test", testUserId, RequiredAction.UPDATE_PASSWORD.name(), true);
    setRequiredActionEnabled("test", testUserId, TermsAndConditions.PROVIDER_ID, false);
    setRequiredActionEnabled("test", testUserId, RequiredAction.UPDATE_PROFILE.name(), false);
    // make UPDATE_PASSWORD on top
    testRealm().flows().raiseRequiredActionPriority(UserModel.RequiredAction.UPDATE_PASSWORD.name());
    testRealm().flows().raiseRequiredActionPriority(UserModel.RequiredAction.UPDATE_PASSWORD.name());
    // Login
    loginPage.open();
    loginPage.login("test-user@localhost", "password");
    // change password
    changePasswordPage.assertCurrent();
    changePasswordPage.changePassword("new-password", "new-password");
    events.expectRequiredAction(EventType.UPDATE_PASSWORD).assertEvent();
    // CONFIGURE_TOTP
    totpPage.assertCurrent();
    totpPage.clickManual();
    String pageSource = driver.getPageSource();
    assertThat(pageSource, not(containsString("Unable to scan?")));
    assertThat(pageSource, containsString("Scan barcode?"));
    TimeBasedOTP totp = new TimeBasedOTP();
    totpPage.configure(totp.generateTOTP(totpPage.getTotpSecret()), "userLabel");
    events.expectRequiredAction(EventType.UPDATE_TOTP).assertEvent();
    // Logined
    appPage.assertCurrent();
    assertThat(appPage.getRequestType(), is(RequestType.AUTH_RESPONSE));
    events.expectLogin().assertEvent();
}
Also used : TimeBasedOTP(org.keycloak.models.utils.TimeBasedOTP) Matchers.containsString(org.hamcrest.Matchers.containsString) Test(org.junit.Test) AbstractTestRealmKeycloakTest(org.keycloak.testsuite.AbstractTestRealmKeycloakTest)

Example 4 with TimeBasedOTP

use of org.keycloak.models.utils.TimeBasedOTP in project keycloak by keycloak.

the class AbstractMigrationTest method testCredentialsMigratedToNewFormat.

protected void testCredentialsMigratedToNewFormat() {
    log.info("testing user's credentials migrated to new format with secretData and credentialData");
    // Try to login with password+otp after the migration
    try {
        oauth.realm(MIGRATION);
        oauth.clientId("migration-test-client");
        TimeBasedOTP otpGenerator = new TimeBasedOTP("HmacSHA1", 8, 40, 1);
        String otp = otpGenerator.generateTOTP("dSdmuHLQhkm54oIm0A0S");
        // Try invalid password first
        OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("secret", "migration-test-user", "password", otp);
        Assert.assertNull(response.getAccessToken());
        Assert.assertNotNull(response.getError());
        // Try invalid OTP then
        response = oauth.doGrantAccessTokenRequest("secret", "migration-test-user", "password2", "invalid");
        Assert.assertNull(response.getAccessToken());
        Assert.assertNotNull(response.getError());
        // Try successful login now
        response = oauth.doGrantAccessTokenRequest("secret", "migration-test-user", "password2", otp);
        Assert.assertNull(response.getError());
        AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
        assertEquals("migration-test-user", accessToken.getPreferredUsername());
    } catch (Exception e) {
        throw new AssertionError("Failed to login with user 'migration-test-user' after migration", e);
    }
}
Also used : TimeBasedOTP(org.keycloak.models.utils.TimeBasedOTP) OAuthClient(org.keycloak.testsuite.util.OAuthClient) AccessToken(org.keycloak.representations.AccessToken) IOException(java.io.IOException)

Example 5 with TimeBasedOTP

use of org.keycloak.models.utils.TimeBasedOTP in project keycloak by keycloak.

the class SigningInTest method beforeSigningInTest.

@Before
public void beforeSigningInTest() {
    passwordCredentialType = signingInPage.getCredentialType(PasswordCredentialModel.TYPE);
    otpCredentialType = signingInPage.getCredentialType(OTPCredentialModel.TYPE);
    RealmRepresentation realm = testRealmResource().toRepresentation();
    otpGenerator = new TimeBasedOTP(realm.getOtpPolicyAlgorithm(), realm.getOtpPolicyDigits(), realm.getOtpPolicyPeriod(), 0);
}
Also used : TimeBasedOTP(org.keycloak.models.utils.TimeBasedOTP) RealmRepresentation(org.keycloak.representations.idm.RealmRepresentation) Before(org.junit.Before)

Aggregations

TimeBasedOTP (org.keycloak.models.utils.TimeBasedOTP)10 Test (org.junit.Test)5 RealmRepresentation (org.keycloak.representations.idm.RealmRepresentation)3 UserCredentialModel (org.keycloak.models.UserCredentialModel)2 HmacOTP (org.keycloak.models.utils.HmacOTP)2 EventRepresentation (org.keycloak.representations.idm.EventRepresentation)2 AbstractTestRealmKeycloakTest (org.keycloak.testsuite.AbstractTestRealmKeycloakTest)2 IOException (java.io.IOException)1 Calendar (java.util.Calendar)1 Matchers.containsString (org.hamcrest.Matchers.containsString)1 Before (org.junit.Before)1 CredentialModel (org.keycloak.credential.CredentialModel)1 PasswordHashProvider (org.keycloak.credential.hash.PasswordHashProvider)1 OTPPolicy (org.keycloak.models.OTPPolicy)1 PasswordPolicy (org.keycloak.models.PasswordPolicy)1 OTPCredentialModel (org.keycloak.models.credential.OTPCredentialModel)1 PasswordUserCredentialModel (org.keycloak.models.credential.PasswordUserCredentialModel)1 OTPCredentialData (org.keycloak.models.credential.dto.OTPCredentialData)1 OTPSecretData (org.keycloak.models.credential.dto.OTPSecretData)1 AccessToken (org.keycloak.representations.AccessToken)1