keycloak-aplcache

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;
         }