Search in sources :

Example 1 with PasswordPolicy

use of org.keycloak.models.PasswordPolicy in project keycloak by keycloak.

the class HistoryPasswordPolicyProvider method validate.

@Override
public PolicyError validate(RealmModel realm, UserModel user, String password) {
    PasswordPolicy policy = session.getContext().getRealm().getPasswordPolicy();
    int passwordHistoryPolicyValue = policy.getPolicyConfig(PasswordPolicy.PASSWORD_HISTORY_ID);
    if (passwordHistoryPolicyValue != -1) {
        if (session.userCredentialManager().getStoredCredentialsByTypeStream(realm, user, PasswordCredentialModel.TYPE).map(PasswordCredentialModel::createFromCredentialModel).anyMatch(passwordCredential -> {
            PasswordHashProvider hash = session.getProvider(PasswordHashProvider.class, passwordCredential.getPasswordCredentialData().getAlgorithm());
            return hash != null && hash.verify(password, passwordCredential);
        })) {
            return new PolicyError(ERROR_MESSAGE, passwordHistoryPolicyValue);
        }
        if (passwordHistoryPolicyValue > 0) {
            if (this.getRecent(session.userCredentialManager().getStoredCredentialsByTypeStream(realm, user, PasswordCredentialModel.PASSWORD_HISTORY), passwordHistoryPolicyValue - 1).map(PasswordCredentialModel::createFromCredentialModel).anyMatch(passwordCredential -> {
                PasswordHashProvider hash = session.getProvider(PasswordHashProvider.class, passwordCredential.getPasswordCredentialData().getAlgorithm());
                return hash.verify(password, passwordCredential);
            })) {
                return new PolicyError(ERROR_MESSAGE, passwordHistoryPolicyValue);
            }
        }
    }
    return null;
}
Also used : PasswordPolicy(org.keycloak.models.PasswordPolicy) PasswordHashProvider(org.keycloak.credential.hash.PasswordHashProvider)

Example 2 with PasswordPolicy

use of org.keycloak.models.PasswordPolicy in project keycloak by keycloak.

the class DefaultPasswordPolicyManagerProvider method getProviders.

private List<PasswordPolicyProvider> getProviders(RealmModel realm, KeycloakSession session) {
    LinkedList<PasswordPolicyProvider> list = new LinkedList<>();
    PasswordPolicy policy = realm.getPasswordPolicy();
    for (String id : policy.getPolicies()) {
        PasswordPolicyProvider provider = session.getProvider(PasswordPolicyProvider.class, id);
        list.add(provider);
    }
    return list;
}
Also used : PasswordPolicy(org.keycloak.models.PasswordPolicy) LinkedList(java.util.LinkedList)

Example 3 with PasswordPolicy

use of org.keycloak.models.PasswordPolicy in project keycloak by keycloak.

the class PasswordPolicyTest method testRegexPatterns.

@Test
public void testRegexPatterns() {
    testingClient.server("passwordPolicy").run(session -> {
        RealmModel realmModel = session.getContext().getRealm();
        PasswordPolicyManagerProvider policyManager = session.getProvider(PasswordPolicyManagerProvider.class);
        PasswordPolicy policy = null;
        try {
            realmModel.setPasswordPolicy(PasswordPolicy.parse(session, "regexPattern"));
            fail("Expected NullPointerException: Regex Pattern cannot be null.");
        } catch (ModelException e) {
            assertEquals("Invalid config for regexPattern: Config required", e.getMessage());
        }
        try {
            realmModel.setPasswordPolicy(PasswordPolicy.parse(session, "regexPattern(*)"));
            fail("Expected PatternSyntaxException: Regex Pattern cannot be null.");
        } catch (ModelException e) {
            assertEquals("Invalid config for regexPattern: Not a valid regular expression", e.getMessage());
        }
        try {
            realmModel.setPasswordPolicy(PasswordPolicy.parse(session, "regexPattern(*,**)"));
            fail("Expected PatternSyntaxException: Regex Pattern cannot be null.");
        } catch (ModelException e) {
            assertEquals("Invalid config for regexPattern: Not a valid regular expression", e.getMessage());
        }
        // Fails to match one of the regex pattern
        realmModel.setPasswordPolicy(PasswordPolicy.parse(session, "regexPattern(jdoe) and regexPattern(j*d)"));
        Assert.assertEquals("invalidPasswordRegexPatternMessage", policyManager.validate("jdoe", "jdoe").getMessage());
        // //Fails to match all of the regex patterns
        realmModel.setPasswordPolicy(PasswordPolicy.parse(session, "regexPattern(j*p) and regexPattern(j*d) and regexPattern(adoe)"));
        Assert.assertEquals("invalidPasswordRegexPatternMessage", policyManager.validate("jdoe", "jdoe").getMessage());
        realmModel.setPasswordPolicy(PasswordPolicy.parse(session, "regexPattern([a-z][a-z][a-z][a-z][0-9])"));
        Assert.assertEquals("invalidPasswordRegexPatternMessage", policyManager.validate("jdoe", "jdoe").getMessage());
        realmModel.setPasswordPolicy(PasswordPolicy.parse(session, "regexPattern(jdoe)"));
        assertNull(policyManager.validate("jdoe", "jdoe"));
        realmModel.setPasswordPolicy(PasswordPolicy.parse(session, "regexPattern([a-z][a-z][a-z][a-z][0-9])"));
        assertNull(policyManager.validate("jdoe", "jdoe0"));
    });
}
Also used : RealmModel(org.keycloak.models.RealmModel) ModelException(org.keycloak.models.ModelException) PasswordPolicyManagerProvider(org.keycloak.policy.PasswordPolicyManagerProvider) PasswordPolicy(org.keycloak.models.PasswordPolicy) Test(org.junit.Test) AbstractKeycloakTest(org.keycloak.testsuite.AbstractKeycloakTest)

Example 4 with PasswordPolicy

use of org.keycloak.models.PasswordPolicy in project keycloak by keycloak.

the class BackwardsCompatibilityUserStorage method updateCredential.

@Override
public boolean updateCredential(RealmModel realm, UserModel user, CredentialInput input) {
    if (!(input instanceof UserCredentialModel))
        return false;
    if (input.getType().equals(UserCredentialModel.PASSWORD)) {
        // Compatibility with 4.8.3 - Using "legacy" type PasswordUserCredentialModel
        if (!(input instanceof PasswordUserCredentialModel)) {
            log.warn("Input is not PasswordUserCredentialModel");
            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);
        CredentialModel newPassword = new CredentialModel();
        newPassword.setType(CredentialModel.PASSWORD);
        long createdDate = Time.currentTimeMillis();
        newPassword.setCreatedDate(createdDate);
        // Compatibility with 4.8.3 - Using "legacy" signature of the method on hashProvider
        hashProvider.encode(userCredentialModel.getValue(), policy.getHashIterations(), newPassword);
        // Test expected values of credentialModel
        assertEquals(newPassword.getAlgorithm(), policy.getHashAlgorithm());
        assertNotNull(newPassword.getValue());
        assertNotNull(newPassword.getSalt());
        users.get(translateUserName(user.getUsername())).hashedPassword = newPassword;
        UserCache userCache = session.userCache();
        if (userCache != null) {
            userCache.evict(realm, user);
        }
        return true;
    } else if (isOTPType(input.getType())) {
        UserCredentialModel otpCredential = (UserCredentialModel) input;
        // Those are not supposed to be set when calling this method in Keycloak 4.8.3 for password credential
        assertNull(otpCredential.getDevice());
        assertNull(otpCredential.getAlgorithm());
        OTPPolicy otpPolicy = session.getContext().getRealm().getOTPPolicy();
        CredentialModel newOTP = new CredentialModel();
        newOTP.setType(input.getType());
        long createdDate = Time.currentTimeMillis();
        newOTP.setCreatedDate(createdDate);
        newOTP.setValue(otpCredential.getValue());
        newOTP.setCounter(otpPolicy.getInitialCounter());
        newOTP.setDigits(otpPolicy.getDigits());
        newOTP.setAlgorithm(otpPolicy.getAlgorithm());
        newOTP.setPeriod(otpPolicy.getPeriod());
        users.get(translateUserName(user.getUsername())).otp = newOTP;
        return true;
    } else {
        log.infof("Attempt to update unsupported credential of type: %s", input.getType());
        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) PasswordPolicy(org.keycloak.models.PasswordPolicy) OTPPolicy(org.keycloak.models.OTPPolicy) UserCache(org.keycloak.models.cache.UserCache) PasswordUserCredentialModel(org.keycloak.models.credential.PasswordUserCredentialModel) UserCredentialModel(org.keycloak.models.UserCredentialModel) PasswordHashProvider(org.keycloak.credential.hash.PasswordHashProvider)

Example 5 with PasswordPolicy

use of org.keycloak.models.PasswordPolicy 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)

Aggregations

PasswordPolicy (org.keycloak.models.PasswordPolicy)8 PasswordHashProvider (org.keycloak.credential.hash.PasswordHashProvider)5 UserCredentialModel (org.keycloak.models.UserCredentialModel)4 UserCache (org.keycloak.models.cache.UserCache)3 PasswordCredentialModel (org.keycloak.models.credential.PasswordCredentialModel)3 CredentialModel (org.keycloak.credential.CredentialModel)2 ModelException (org.keycloak.models.ModelException)2 OnUserCache (org.keycloak.models.cache.OnUserCache)2 PasswordUserCredentialModel (org.keycloak.models.credential.PasswordUserCredentialModel)2 PasswordPolicyManagerProvider (org.keycloak.policy.PasswordPolicyManagerProvider)2 LinkedList (java.util.LinkedList)1 Test (org.junit.Test)1 OTPPolicy (org.keycloak.models.OTPPolicy)1 RealmModel (org.keycloak.models.RealmModel)1 TimeBasedOTP (org.keycloak.models.utils.TimeBasedOTP)1 PolicyError (org.keycloak.policy.PolicyError)1 AbstractKeycloakTest (org.keycloak.testsuite.AbstractKeycloakTest)1