Merge pull request #3286 from patriot1burke/master
remove UserCredValueModel and hold hash providers
This commit is contained in:
commit
a89dbabc92
19 changed files with 16 additions and 542 deletions
|
@ -27,6 +27,7 @@
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<module name="org.keycloak.keycloak-common"/>
|
<module name="org.keycloak.keycloak-common"/>
|
||||||
<module name="org.keycloak.keycloak-core"/>
|
<module name="org.keycloak.keycloak-core"/>
|
||||||
|
<module name="org.keycloak.keycloak-services"/>
|
||||||
<module name="org.keycloak.keycloak-server-spi"/>
|
<module name="org.keycloak.keycloak-server-spi"/>
|
||||||
<module name="org.mongodb.mongo-java-driver"/>
|
<module name="org.mongodb.mongo-java-driver"/>
|
||||||
<module name="org.jboss.logging"/>
|
<module name="org.jboss.logging"/>
|
||||||
|
|
|
@ -52,6 +52,11 @@
|
||||||
<artifactId>keycloak-server-spi</artifactId>
|
<artifactId>keycloak-server-spi</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-services</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jboss.logging</groupId>
|
<groupId>org.jboss.logging</groupId>
|
||||||
<artifactId>jboss-logging</artifactId>
|
<artifactId>jboss-logging</artifactId>
|
||||||
|
|
|
@ -21,7 +21,7 @@ import com.mongodb.BasicDBList;
|
||||||
import com.mongodb.BasicDBObject;
|
import com.mongodb.BasicDBObject;
|
||||||
import com.mongodb.DBCollection;
|
import com.mongodb.DBCollection;
|
||||||
import com.mongodb.WriteResult;
|
import com.mongodb.WriteResult;
|
||||||
import org.keycloak.hash.Pbkdf2PasswordHashProvider;
|
import org.keycloak.credential.hash.Pbkdf2PasswordHashProvider;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ import com.mongodb.BasicDBList;
|
||||||
import com.mongodb.BasicDBObject;
|
import com.mongodb.BasicDBObject;
|
||||||
import com.mongodb.DBCollection;
|
import com.mongodb.DBCollection;
|
||||||
import com.mongodb.WriteResult;
|
import com.mongodb.WriteResult;
|
||||||
import org.keycloak.hash.Pbkdf2PasswordHashProvider;
|
import org.keycloak.credential.hash.Pbkdf2PasswordHashProvider;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
import org.keycloak.models.utils.HmacOTP;
|
import org.keycloak.models.utils.HmacOTP;
|
||||||
|
|
|
@ -24,7 +24,6 @@ import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.models.PasswordPolicy;
|
import org.keycloak.models.PasswordPolicy;
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
import org.keycloak.models.UserCredentialValueModel;
|
|
||||||
|
|
||||||
import javax.crypto.SecretKeyFactory;
|
import javax.crypto.SecretKeyFactory;
|
||||||
import javax.crypto.spec.PBEKeySpec;
|
import javax.crypto.spec.PBEKeySpec;
|
||||||
|
@ -43,11 +42,11 @@ public class Pbkdf2PasswordHashProvider implements PasswordHashProviderFactory,
|
||||||
private static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";
|
private static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";
|
||||||
private static final int DERIVED_KEY_SIZE = 512;
|
private static final int DERIVED_KEY_SIZE = 512;
|
||||||
|
|
||||||
public UserCredentialValueModel encode(String rawPassword, int iterations) {
|
public CredentialModel encode(String rawPassword, int iterations) {
|
||||||
byte[] salt = getSalt();
|
byte[] salt = getSalt();
|
||||||
String encodedPassword = encode(rawPassword, iterations, salt);
|
String encodedPassword = encode(rawPassword, iterations, salt);
|
||||||
|
|
||||||
UserCredentialValueModel credentials = new UserCredentialValueModel();
|
CredentialModel credentials = new CredentialModel();
|
||||||
credentials.setAlgorithm(ID);
|
credentials.setAlgorithm(ID);
|
||||||
credentials.setType(UserCredentialModel.PASSWORD);
|
credentials.setType(UserCredentialModel.PASSWORD);
|
||||||
credentials.setSalt(salt);
|
credentials.setSalt(salt);
|
||||||
|
@ -56,10 +55,6 @@ public class Pbkdf2PasswordHashProvider implements PasswordHashProviderFactory,
|
||||||
return credentials;
|
return credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean verify(String rawPassword, UserCredentialValueModel credential) {
|
|
||||||
return encode(rawPassword, credential.getHashIterations(), credential.getSalt()).equals(credential.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean policyCheck(PasswordPolicy policy, CredentialModel credential) {
|
public boolean policyCheck(PasswordPolicy policy, CredentialModel credential) {
|
||||||
return credential.getHashIterations() == policy.getHashIterations() && ID.equals(credential.getAlgorithm());
|
return credential.getHashIterations() == policy.getHashIterations() && ID.equals(credential.getAlgorithm());
|
|
@ -1,61 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
||||||
* and other contributors as indicated by the @author tags.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.keycloak.hash;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.PasswordPolicy;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.UserCredentialValueModel;
|
|
||||||
import org.keycloak.policy.HashAlgorithmPasswordPolicyProviderFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
|
||||||
*/
|
|
||||||
public class PasswordHashManager {
|
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(PasswordHashManager.class);
|
|
||||||
|
|
||||||
public static UserCredentialValueModel encode(KeycloakSession session, RealmModel realm, String rawPassword) {
|
|
||||||
return encode(session, realm.getPasswordPolicy(), rawPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UserCredentialValueModel encode(KeycloakSession session, PasswordPolicy passwordPolicy, String rawPassword) {
|
|
||||||
PasswordHashProvider provider = session.getProvider(PasswordHashProvider.class, passwordPolicy.getHashAlgorithm());
|
|
||||||
if (provider == null) {
|
|
||||||
log.warnv("Could not find hash provider {0} from password policy, using default provider {1}", passwordPolicy.getHashAlgorithm(), HashAlgorithmPasswordPolicyProviderFactory.DEFAULT_VALUE);
|
|
||||||
provider = session.getProvider(PasswordHashProvider.class, HashAlgorithmPasswordPolicyProviderFactory.DEFAULT_VALUE);
|
|
||||||
}
|
|
||||||
return provider.encode(rawPassword, passwordPolicy.getHashIterations());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean verify(KeycloakSession session, RealmModel realm, String password, UserCredentialValueModel credential) {
|
|
||||||
return verify(session, realm.getPasswordPolicy(), password, credential);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean verify(KeycloakSession session, PasswordPolicy passwordPolicy, String password, UserCredentialValueModel credential) {
|
|
||||||
String algorithm = credential.getAlgorithm() != null ? credential.getAlgorithm() : passwordPolicy.getHashAlgorithm();
|
|
||||||
PasswordHashProvider provider = session.getProvider(PasswordHashProvider.class, algorithm);
|
|
||||||
if (provider == null) {
|
|
||||||
log.warnv("Could not find hash provider {0} for password", algorithm);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return provider.verify(password, credential);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
||||||
* and other contributors as indicated by the @author tags.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.keycloak.hash;
|
|
||||||
|
|
||||||
import org.keycloak.models.UserCredentialValueModel;
|
|
||||||
import org.keycloak.provider.Provider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:me@tsudot.com">Kunal Kerkar</a>
|
|
||||||
*/
|
|
||||||
public interface PasswordHashProvider extends Provider {
|
|
||||||
|
|
||||||
UserCredentialValueModel encode(String rawPassword, int iterations);
|
|
||||||
|
|
||||||
boolean verify(String rawPassword, UserCredentialValueModel credential);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
||||||
* and other contributors as indicated by the @author tags.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.keycloak.hash;
|
|
||||||
|
|
||||||
import org.keycloak.provider.ProviderFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:me@tsudot.com">Kunal Kerkar</a>
|
|
||||||
*/
|
|
||||||
public interface PasswordHashProviderFactory extends ProviderFactory<PasswordHashProvider> {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
||||||
* and other contributors as indicated by the @author tags.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.keycloak.hash;
|
|
||||||
|
|
||||||
import org.keycloak.provider.Provider;
|
|
||||||
import org.keycloak.provider.ProviderFactory;
|
|
||||||
import org.keycloak.provider.Spi;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:me@tsudot.com">Kunal Kerkar</a>
|
|
||||||
*/
|
|
||||||
public class PasswordHashSpi implements Spi {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isInternal() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "password-hash";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<? extends Provider> getProviderClass() {
|
|
||||||
return PasswordHashProvider.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
|
||||||
return PasswordHashProviderFactory.class;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,108 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
||||||
* and other contributors as indicated by the @author tags.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.keycloak.hash;
|
|
||||||
|
|
||||||
import org.keycloak.Config;
|
|
||||||
import org.keycloak.common.util.Base64;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
|
||||||
import org.keycloak.models.UserCredentialModel;
|
|
||||||
import org.keycloak.models.UserCredentialValueModel;
|
|
||||||
|
|
||||||
import javax.crypto.SecretKeyFactory;
|
|
||||||
import javax.crypto.spec.PBEKeySpec;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.security.spec.InvalidKeySpecException;
|
|
||||||
import java.security.spec.KeySpec;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:me@tsudot.com">Kunal Kerkar</a>
|
|
||||||
*/
|
|
||||||
public class Pbkdf2PasswordHashProvider implements PasswordHashProviderFactory, PasswordHashProvider {
|
|
||||||
|
|
||||||
public static final String ID = "pbkdf2";
|
|
||||||
|
|
||||||
private static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";
|
|
||||||
private static final int DERIVED_KEY_SIZE = 512;
|
|
||||||
|
|
||||||
public UserCredentialValueModel encode(String rawPassword, int iterations) {
|
|
||||||
byte[] salt = getSalt();
|
|
||||||
String encodedPassword = encode(rawPassword, iterations, salt);
|
|
||||||
|
|
||||||
UserCredentialValueModel credentials = new UserCredentialValueModel();
|
|
||||||
credentials.setAlgorithm(ID);
|
|
||||||
credentials.setType(UserCredentialModel.PASSWORD);
|
|
||||||
credentials.setSalt(salt);
|
|
||||||
credentials.setHashIterations(iterations);
|
|
||||||
credentials.setValue(encodedPassword);
|
|
||||||
return credentials;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean verify(String rawPassword, UserCredentialValueModel credential) {
|
|
||||||
return encode(rawPassword, credential.getHashIterations(), credential.getSalt()).equals(credential.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PasswordHashProvider create(KeycloakSession session) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Config.Scope config) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postInit(KeycloakSessionFactory factory) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String encode(String rawPassword, int iterations, byte[] salt) {
|
|
||||||
KeySpec spec = new PBEKeySpec(rawPassword.toCharArray(), salt, iterations, DERIVED_KEY_SIZE);
|
|
||||||
|
|
||||||
try {
|
|
||||||
byte[] key = getSecretKeyFactory().generateSecret(spec).getEncoded();
|
|
||||||
return Base64.encodeBytes(key);
|
|
||||||
} catch (InvalidKeySpecException e) {
|
|
||||||
throw new RuntimeException("Credential could not be encoded", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] getSalt() {
|
|
||||||
byte[] buffer = new byte[16];
|
|
||||||
SecureRandom secureRandom = new SecureRandom();
|
|
||||||
secureRandom.nextBytes(buffer);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SecretKeyFactory getSecretKeyFactory() {
|
|
||||||
try {
|
|
||||||
return SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new RuntimeException("PBKDF2 algorithm not found", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,130 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
||||||
* and other contributors as indicated by the @author tags.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.keycloak.models;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used just in cases when we want to "directly" update or retrieve the hash or salt of user credential (For example during export/import)
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
public class UserCredentialValueModel implements Serializable {
|
|
||||||
private String id;
|
|
||||||
private String type;
|
|
||||||
private String value;
|
|
||||||
private String device;
|
|
||||||
private byte[] salt;
|
|
||||||
private int hashIterations;
|
|
||||||
private Long createdDate;
|
|
||||||
|
|
||||||
// otp stuff
|
|
||||||
private int counter;
|
|
||||||
private String algorithm;
|
|
||||||
private int digits;
|
|
||||||
private int period;
|
|
||||||
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(String type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDevice() {
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDevice(String device) {
|
|
||||||
this.device = device;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getSalt() {
|
|
||||||
return salt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSalt(byte[] salt) {
|
|
||||||
this.salt = salt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHashIterations() {
|
|
||||||
return hashIterations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHashIterations(int iterations) {
|
|
||||||
this.hashIterations = iterations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getCreatedDate() {
|
|
||||||
return createdDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreatedDate(Long createdDate) {
|
|
||||||
this.createdDate = createdDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCounter() {
|
|
||||||
return counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCounter(int counter) {
|
|
||||||
this.counter = counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAlgorithm() {
|
|
||||||
return algorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAlgorithm(String algorithm) {
|
|
||||||
this.algorithm = algorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDigits() {
|
|
||||||
return digits;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDigits(int digits) {
|
|
||||||
this.digits = digits;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPeriod() {
|
|
||||||
return period;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPeriod(int period) {
|
|
||||||
this.period = period;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -35,7 +35,6 @@ import org.keycloak.common.util.MultivaluedHashMap;
|
||||||
import org.keycloak.common.util.UriUtils;
|
import org.keycloak.common.util.UriUtils;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.credential.CredentialModel;
|
import org.keycloak.credential.CredentialModel;
|
||||||
import org.keycloak.hash.Pbkdf2PasswordHashProvider;
|
|
||||||
import org.keycloak.migration.MigrationProvider;
|
import org.keycloak.migration.MigrationProvider;
|
||||||
import org.keycloak.migration.migrators.MigrationUtils;
|
import org.keycloak.migration.migrators.MigrationUtils;
|
||||||
import org.keycloak.models.AuthenticationExecutionModel;
|
import org.keycloak.models.AuthenticationExecutionModel;
|
||||||
|
@ -1434,14 +1433,14 @@ public class RepresentationToModel {
|
||||||
// Could happen when migrating from some early version
|
// Could happen when migrating from some early version
|
||||||
if ((UserCredentialModel.PASSWORD.equals(cred.getType()) || UserCredentialModel.PASSWORD_HISTORY.equals(cred.getType())) &&
|
if ((UserCredentialModel.PASSWORD.equals(cred.getType()) || UserCredentialModel.PASSWORD_HISTORY.equals(cred.getType())) &&
|
||||||
(cred.getAlgorithm().equals(HmacOTP.HMAC_SHA1))) {
|
(cred.getAlgorithm().equals(HmacOTP.HMAC_SHA1))) {
|
||||||
hashedCred.setAlgorithm(Pbkdf2PasswordHashProvider.ID);
|
hashedCred.setAlgorithm("pbkdf2");
|
||||||
} else {
|
} else {
|
||||||
hashedCred.setAlgorithm(cred.getAlgorithm());
|
hashedCred.setAlgorithm(cred.getAlgorithm());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (UserCredentialModel.PASSWORD.equals(cred.getType()) || UserCredentialModel.PASSWORD_HISTORY.equals(cred.getType())) {
|
if (UserCredentialModel.PASSWORD.equals(cred.getType()) || UserCredentialModel.PASSWORD_HISTORY.equals(cred.getType())) {
|
||||||
hashedCred.setAlgorithm(Pbkdf2PasswordHashProvider.ID);
|
hashedCred.setAlgorithm("pbkdf2");
|
||||||
} else if (UserCredentialModel.isOtp(cred.getType())) {
|
} else if (UserCredentialModel.isOtp(cred.getType())) {
|
||||||
hashedCred.setAlgorithm(HmacOTP.HMAC_SHA1);
|
hashedCred.setAlgorithm(HmacOTP.HMAC_SHA1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
#
|
|
||||||
# Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
||||||
# and other contributors as indicated by the @author tags.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
#
|
|
||||||
|
|
||||||
org.keycloak.hash.Pbkdf2PasswordHashProvider
|
|
|
@ -25,7 +25,6 @@ org.keycloak.models.UserSpi
|
||||||
org.keycloak.models.session.UserSessionPersisterSpi
|
org.keycloak.models.session.UserSessionPersisterSpi
|
||||||
org.keycloak.models.dblock.DBLockSpi
|
org.keycloak.models.dblock.DBLockSpi
|
||||||
org.keycloak.migration.MigrationSpi
|
org.keycloak.migration.MigrationSpi
|
||||||
org.keycloak.hash.PasswordHashSpi
|
|
||||||
org.keycloak.events.EventListenerSpi
|
org.keycloak.events.EventListenerSpi
|
||||||
org.keycloak.events.EventStoreSpi
|
org.keycloak.events.EventStoreSpi
|
||||||
org.keycloak.exportimport.ExportSpi
|
org.keycloak.exportimport.ExportSpi
|
||||||
|
|
|
@ -26,7 +26,7 @@ import org.junit.rules.TemporaryFolder;
|
||||||
import org.keycloak.admin.client.Keycloak;
|
import org.keycloak.admin.client.Keycloak;
|
||||||
import org.keycloak.admin.client.resource.RealmResource;
|
import org.keycloak.admin.client.resource.RealmResource;
|
||||||
import org.keycloak.admin.client.resource.UserResource;
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
import org.keycloak.hash.Pbkdf2PasswordHashProvider;
|
import org.keycloak.credential.hash.Pbkdf2PasswordHashProvider;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.representations.idm.ClientRepresentation;
|
import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
||||||
* and other contributors as indicated by the @author tags.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.keycloak.testsuite.federation.storage;
|
|
||||||
|
|
||||||
import org.keycloak.hash.PasswordHashProvider;
|
|
||||||
import org.keycloak.models.UserCredentialModel;
|
|
||||||
import org.keycloak.models.UserCredentialValueModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
|
||||||
* @version $Revision: 1 $
|
|
||||||
*/
|
|
||||||
public class PlainTextPasswordProvider implements PasswordHashProvider {
|
|
||||||
@Override
|
|
||||||
public UserCredentialValueModel encode(String rawPassword, int iterations) {
|
|
||||||
UserCredentialValueModel model = new UserCredentialValueModel();
|
|
||||||
model.setType(UserCredentialModel.PASSWORD);
|
|
||||||
model.setValue(rawPassword);
|
|
||||||
model.setAlgorithm("text");
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean verify(String rawPassword, UserCredentialValueModel credential) {
|
|
||||||
return rawPassword.equals(credential.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
||||||
* and other contributors as indicated by the @author tags.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.keycloak.testsuite.federation.storage;
|
|
||||||
|
|
||||||
import org.keycloak.Config;
|
|
||||||
import org.keycloak.hash.PasswordHashProvider;
|
|
||||||
import org.keycloak.hash.PasswordHashProviderFactory;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
|
||||||
* @version $Revision: 1 $
|
|
||||||
*/
|
|
||||||
public class PlainTextPasswordProviderFactory implements PasswordHashProviderFactory {
|
|
||||||
@Override
|
|
||||||
public PasswordHashProvider create(KeycloakSession session) {
|
|
||||||
return new PlainTextPasswordProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Config.Scope config) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postInit(KeycloakSessionFactory factory) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return "text";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
org.keycloak.testsuite.federation.storage.PlainTextPasswordProviderFactory
|
|
|
@ -29,8 +29,8 @@ import org.jboss.aesh.console.command.invocation.CommandInvocation;
|
||||||
import org.jboss.aesh.console.command.registry.AeshCommandRegistryBuilder;
|
import org.jboss.aesh.console.command.registry.AeshCommandRegistryBuilder;
|
||||||
import org.jboss.aesh.console.command.registry.CommandRegistry;
|
import org.jboss.aesh.console.command.registry.CommandRegistry;
|
||||||
import org.keycloak.common.util.Base64;
|
import org.keycloak.common.util.Base64;
|
||||||
import org.keycloak.hash.Pbkdf2PasswordHashProvider;
|
import org.keycloak.credential.CredentialModel;
|
||||||
import org.keycloak.models.UserCredentialValueModel;
|
import org.keycloak.credential.hash.Pbkdf2PasswordHashProvider;
|
||||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.representations.idm.UserRepresentation;
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
|
@ -153,7 +153,7 @@ public class AddUser {
|
||||||
user.setUsername(userName);
|
user.setUsername(userName);
|
||||||
user.setCredentials(new LinkedList<CredentialRepresentation>());
|
user.setCredentials(new LinkedList<CredentialRepresentation>());
|
||||||
|
|
||||||
UserCredentialValueModel credentialValueModel = new Pbkdf2PasswordHashProvider().encode(password, iterations > 0 ? iterations : DEFAULT_HASH_ITERATIONS);
|
CredentialModel credentialValueModel = new Pbkdf2PasswordHashProvider().encode(password, iterations > 0 ? iterations : DEFAULT_HASH_ITERATIONS);
|
||||||
|
|
||||||
CredentialRepresentation credentials = new CredentialRepresentation();
|
CredentialRepresentation credentials = new CredentialRepresentation();
|
||||||
credentials.setType(credentialValueModel.getType());
|
credentials.setType(credentialValueModel.getType());
|
||||||
|
|
Loading…
Reference in a new issue