Merge pull request #4717 from patriot1burke/master

KEYCLOAK-5715
This commit is contained in:
Bill Burke 2017-11-17 12:59:36 -05:00 committed by GitHub
commit 7c0c48da01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 4 deletions

View file

@ -73,6 +73,16 @@ public class Pbkdf2PasswordHashProvider implements PasswordHashProvider {
credential.setValue(encodedPassword);
}
@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());

View file

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

View file

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