Details
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java
index c209979..a773d9d 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java
@@ -611,7 +611,7 @@ public class UserCacheSession implements UserCache {
@Override
public List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
- return getUsers(realm, firstResult, maxResults, false);
+ return getUsers(realm, firstResult, maxResults, false);
}
@Override
diff --git a/server-spi/src/main/java/org/keycloak/credential/hash/PasswordHashProvider.java b/server-spi/src/main/java/org/keycloak/credential/hash/PasswordHashProvider.java
index ee555c2..1745c4a 100644
--- a/server-spi/src/main/java/org/keycloak/credential/hash/PasswordHashProvider.java
+++ b/server-spi/src/main/java/org/keycloak/credential/hash/PasswordHashProvider.java
@@ -29,5 +29,10 @@ public interface PasswordHashProvider extends Provider {
void encode(String rawPassword, int iterations, CredentialModel credential);
+ default
+ String encode(String rawPassword, int iterations) {
+ return rawPassword;
+ }
+
boolean verify(String rawPassword, CredentialModel credential);
}
diff --git a/server-spi-private/src/main/java/org/keycloak/credential/hash/Pbkdf2PasswordHashProvider.java b/server-spi-private/src/main/java/org/keycloak/credential/hash/Pbkdf2PasswordHashProvider.java
index f010dd3..e71ff6d 100644
--- a/server-spi-private/src/main/java/org/keycloak/credential/hash/Pbkdf2PasswordHashProvider.java
+++ b/server-spi-private/src/main/java/org/keycloak/credential/hash/Pbkdf2PasswordHashProvider.java
@@ -74,6 +74,16 @@ public class Pbkdf2PasswordHashProvider implements PasswordHashProvider {
}
@Override
+ public String encode(String rawPassword, int iterations) {
+ if (iterations == -1) {
+ iterations = defaultIterations;
+ }
+
+ byte[] salt = getSalt();
+ return encode(rawPassword, iterations, salt);
+ }
+
+ @Override
public boolean verify(String rawPassword, CredentialModel credential) {
return encode(rawPassword, credential.getHashIterations(), credential.getSalt()).equals(credential.getValue());
}
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/browser/AbstractUsernameFormAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/browser/AbstractUsernameFormAuthenticator.java
index a0f13bc..72c10f5 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/browser/AbstractUsernameFormAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/browser/AbstractUsernameFormAuthenticator.java
@@ -22,9 +22,12 @@ import org.keycloak.authentication.AbstractFormAuthenticator;
import org.keycloak.authentication.AuthenticationFlowContext;
import org.keycloak.authentication.AuthenticationFlowError;
import org.keycloak.credential.CredentialInput;
+import org.keycloak.credential.CredentialModel;
+import org.keycloak.credential.hash.PasswordHashProvider;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.models.ModelDuplicateException;
+import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.KeycloakModelUtils;
@@ -83,8 +86,32 @@ public abstract class AbstractUsernameFormAuthenticator extends AbstractFormAuth
return challengeResponse;
}
+ protected void runDefaultDummyHash(AuthenticationFlowContext context) {
+ PasswordHashProvider hash = context.getSession().getProvider(PasswordHashProvider.class, PasswordPolicy.HASH_ALGORITHM_DEFAULT);
+ hash.encode("dummypassword", PasswordPolicy.HASH_ITERATIONS_DEFAULT);
+ }
+
+ protected void dummyHash(AuthenticationFlowContext context) {
+ PasswordPolicy policy = context.getRealm().getPasswordPolicy();
+ if (policy == null) {
+ runDefaultDummyHash(context);
+ return;
+ } else {
+ PasswordHashProvider hash = context.getSession().getProvider(PasswordHashProvider.class, policy.getHashAlgorithm());
+ if (hash == null) {
+ runDefaultDummyHash(context);
+ return;
+
+ } else {
+ hash.encode("dummypassword", policy.getHashIterations());
+ }
+ }
+
+ }
+
public boolean invalidUser(AuthenticationFlowContext context, UserModel user) {
if (user == null) {
+ dummyHash(context);
context.getEvent().error(Errors.USER_NOT_FOUND);
Response challengeResponse = invalidUser(context);
context.failureChallenge(AuthenticationFlowError.INVALID_USER, challengeResponse);
@@ -144,15 +171,15 @@ public abstract class AbstractUsernameFormAuthenticator extends AbstractFormAuth
return false;
}
- if (invalidUser(context, user)){
+ if (invalidUser(context, user)) {
return false;
}
- if (!validatePassword(context, user, inputData)){
+ if (!validatePassword(context, user, inputData)) {
return false;
}
- if(!enabledUser(context, user)){
+ if (!enabledUser(context, user)) {
return false;
}