mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
ACS-4759 Replace default password hashing algorithm. (#1789)
ACS-4759 Replace default password hashing algorithm with bcrypt10. Update tests to use sha256 hashing and fix tests that relied on md4 being the default hashing algorithm. Remove test for default password hashing algorithm since this is being overridden for the tests anyway.
This commit is contained in:
@@ -1149,7 +1149,7 @@ smart.folders.config.type.templates.path=${spaces.dictionary.childname}/${spaces
|
|||||||
smart.folders.config.type.templates.qname.filter=none
|
smart.folders.config.type.templates.qname.filter=none
|
||||||
|
|
||||||
# Preferred password encoding, md4, sha256, bcrypt10
|
# Preferred password encoding, md4, sha256, bcrypt10
|
||||||
system.preferred.password.encoding=md4
|
system.preferred.password.encoding=bcrypt10
|
||||||
|
|
||||||
# Upgrade Password Hash Job
|
# Upgrade Password Hash Job
|
||||||
system.upgradePasswordHash.jobBatchSize=100
|
system.upgradePasswordHash.jobBatchSize=100
|
||||||
|
@@ -26,15 +26,12 @@
|
|||||||
package org.alfresco.repo.security.authentication;
|
package org.alfresco.repo.security.authentication;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.transaction.Status;
|
import javax.transaction.Status;
|
||||||
import javax.transaction.UserTransaction;
|
import javax.transaction.UserTransaction;
|
||||||
|
|
||||||
@@ -48,7 +45,6 @@ import net.sf.acegisecurity.DisabledException;
|
|||||||
import net.sf.acegisecurity.LockedException;
|
import net.sf.acegisecurity.LockedException;
|
||||||
import net.sf.acegisecurity.UserDetails;
|
import net.sf.acegisecurity.UserDetails;
|
||||||
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.admin.SysAdminParamsImpl;
|
import org.alfresco.repo.admin.SysAdminParamsImpl;
|
||||||
@@ -519,50 +515,48 @@ public class AuthenticationTest extends TestCase
|
|||||||
assertTrue("The user should exist", dao.userExists(userName));
|
assertTrue("The user should exist", dao.userExists(userName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCreateAndyUserAndOtherCRUD() throws NoSuchAlgorithmException, UnsupportedEncodingException
|
public void testCreateAndyUserAndUpdatePassword()
|
||||||
{
|
{
|
||||||
RepositoryAuthenticationDao dao = createRepositoryAuthenticationDao();
|
RepositoryAuthenticationDao dao = createRepositoryAuthenticationDao();
|
||||||
|
|
||||||
dao.createUser("Andy", "cabbage".toCharArray());
|
dao.createUser("Andy", "cabbage".toCharArray());
|
||||||
assertNotNull(dao.getUserOrNull("Andy"));
|
assertNotNull(dao.getUserOrNull("Andy"));
|
||||||
|
|
||||||
UserDetails AndyDetails = (UserDetails) dao.loadUserByUsername("Andy");
|
RepositoryAuthenticatedUser andyDetails = (RepositoryAuthenticatedUser) dao.loadUserByUsername("Andy");
|
||||||
assertNotNull(AndyDetails);
|
assertNotNull("User unexpectedly null", andyDetails);
|
||||||
assertEquals("Andy", AndyDetails.getUsername());
|
assertEquals("Unexpected username", "Andy", andyDetails.getUsername());
|
||||||
// assertNotNull(dao.getSalt(AndyDetails));
|
Object originalSalt = andyDetails.getSalt();
|
||||||
assertTrue(AndyDetails.isAccountNonExpired());
|
assertNotNull("Salt was not generated", originalSalt);
|
||||||
assertTrue(AndyDetails.isAccountNonLocked());
|
assertTrue("Account unexpectedly expired", andyDetails.isAccountNonExpired());
|
||||||
assertTrue(AndyDetails.isCredentialsNonExpired());
|
assertTrue("Account unexpectedly locked", andyDetails.isAccountNonLocked());
|
||||||
assertTrue(AndyDetails.isEnabled());
|
assertTrue("Credentials unexpectedly expired", andyDetails.isCredentialsNonExpired());
|
||||||
assertNotSame("cabbage", AndyDetails.getPassword());
|
assertTrue("User unexpectedly disabled", andyDetails.isEnabled());
|
||||||
assertTrue(compositePasswordEncoder.matches(compositePasswordEncoder.getPreferredEncoding(),"cabbage", AndyDetails.getPassword(), null));
|
assertNotSame("Password was not hashed", "cabbage", andyDetails.getPassword());
|
||||||
assertEquals(1, AndyDetails.getAuthorities().length);
|
assertTrue("Failed to recalculate same password hash", compositePasswordEncoder.matches(compositePasswordEncoder.getPreferredEncoding(),"cabbage", andyDetails.getPassword(), originalSalt));
|
||||||
|
assertEquals("User does not have a single authority", 1, andyDetails.getAuthorities().length);
|
||||||
|
|
||||||
// Object oldSalt = dao.getSalt(AndyDetails);
|
|
||||||
dao.updateUser("Andy", "carrot".toCharArray());
|
dao.updateUser("Andy", "carrot".toCharArray());
|
||||||
UserDetails newDetails = (UserDetails) dao.loadUserByUsername("Andy");
|
RepositoryAuthenticatedUser newDetails = (RepositoryAuthenticatedUser) dao.loadUserByUsername("Andy");
|
||||||
assertNotNull(newDetails);
|
assertNotNull("New details were null", newDetails);
|
||||||
assertEquals("Andy", newDetails.getUsername());
|
assertEquals("New details contain wrong username", "Andy", newDetails.getUsername());
|
||||||
// assertNotNull(dao.getSalt(newDetails));
|
Object updatedSalt = newDetails.getSalt();
|
||||||
assertTrue(newDetails.isAccountNonExpired());
|
assertNotNull("New details contain null salt", updatedSalt);
|
||||||
assertTrue(newDetails.isAccountNonLocked());
|
assertTrue("Updated account is expired", newDetails.isAccountNonExpired());
|
||||||
assertTrue(newDetails.isCredentialsNonExpired());
|
assertTrue("Updated account is locked", newDetails.isAccountNonLocked());
|
||||||
assertTrue(newDetails.isEnabled());
|
assertTrue("Updated account has expired credentials", newDetails.isCredentialsNonExpired());
|
||||||
assertNotSame("carrot", newDetails.getPassword());
|
assertTrue("Updated account is not enabled", newDetails.isEnabled());
|
||||||
assertEquals(1, newDetails.getAuthorities().length);
|
assertNotSame("Updated account contains unhashed password", "carrot", newDetails.getPassword());
|
||||||
|
assertEquals("Updated account should have a single authority", 1, newDetails.getAuthorities().length);
|
||||||
|
assertTrue("Failed to validate updated password hash", compositePasswordEncoder.matches(compositePasswordEncoder.getPreferredEncoding(),"carrot", newDetails.getPassword(), updatedSalt));
|
||||||
|
assertNotSame("Expected salt to be replaced when password was updated", originalSalt, updatedSalt);
|
||||||
|
|
||||||
assertNotSame(AndyDetails.getPassword(), newDetails.getPassword());
|
// Update back to first password again.
|
||||||
RepositoryAuthenticatedUser rau = (RepositoryAuthenticatedUser) newDetails;
|
dao.updateUser("Andy", "cabbage".toCharArray());
|
||||||
assertTrue(compositePasswordEncoder.matchesPassword("carrot", newDetails.getPassword(), null, rau.getHashIndicator()));
|
RepositoryAuthenticatedUser thirdDetails = (RepositoryAuthenticatedUser) dao.loadUserByUsername("Andy");
|
||||||
// assertNotSame(oldSalt, dao.getSalt(newDetails));
|
Object thirdSalt = thirdDetails.getSalt();
|
||||||
|
assertNotSame("New salt should not match original salt", thirdSalt, originalSalt);
|
||||||
//Update again
|
assertNotSame("New salt should not match previous salt", thirdSalt, updatedSalt);
|
||||||
dao.updateUser("Andy", "potato".toCharArray());
|
assertTrue("New password hash was not reproducible", compositePasswordEncoder.matches(compositePasswordEncoder.getPreferredEncoding(), "cabbage", thirdDetails.getPassword(), thirdSalt));
|
||||||
newDetails = (UserDetails) dao.loadUserByUsername("Andy");
|
|
||||||
assertNotNull(newDetails);
|
|
||||||
assertEquals("Andy", newDetails.getUsername());
|
|
||||||
rau = (RepositoryAuthenticatedUser) newDetails;
|
|
||||||
assertTrue(compositePasswordEncoder.matchesPassword("potato", newDetails.getPassword(), null, rau.getHashIndicator()));
|
|
||||||
|
|
||||||
dao.deleteUser("Andy");
|
dao.deleteUser("Andy");
|
||||||
assertFalse("Should not be a cache entry for 'Andy'.", authenticationCache.contains("Andy"));
|
assertFalse("Should not be a cache entry for 'Andy'.", authenticationCache.contains("Andy"));
|
||||||
@@ -1989,131 +1983,142 @@ public class AuthenticationTest extends TestCase
|
|||||||
* Tests the scenario where a user logs in after the system has been upgraded.
|
* Tests the scenario where a user logs in after the system has been upgraded.
|
||||||
* Their password should get re-hashed using the preferred encoding.
|
* Their password should get re-hashed using the preferred encoding.
|
||||||
*/
|
*/
|
||||||
public void testRehashedPasswordOnAuthentication() throws Exception
|
public void testRehashedPasswordOnAuthentication()
|
||||||
{
|
{
|
||||||
// create the Andy authentication
|
// This test requires upgrading from md4 to sha256 hashing.
|
||||||
assertNull(authenticationComponent.getCurrentAuthentication());
|
String defaultPreferredEncoding = compositePasswordEncoder.getPreferredEncoding();
|
||||||
authenticationComponent.setSystemUserAsCurrentUser();
|
compositePasswordEncoder.setPreferredEncoding("md4");
|
||||||
pubAuthenticationService.createAuthentication("Andy", "auth1".toCharArray());
|
|
||||||
|
|
||||||
// find the node representing the Andy user and it's properties
|
try
|
||||||
NodeRef andyUserNodeRef = getRepositoryAuthenticationDao(). getUserOrNull("Andy");
|
{
|
||||||
assertNotNull(andyUserNodeRef);
|
// create the Andy authentication
|
||||||
|
assertNull(authenticationComponent.getCurrentAuthentication());
|
||||||
|
authenticationComponent.setSystemUserAsCurrentUser();
|
||||||
|
pubAuthenticationService.createAuthentication("Andy", "auth1".toCharArray());
|
||||||
|
|
||||||
// ensure the properties are in the state we're expecting
|
// find the node representing the Andy user and its properties
|
||||||
Map<QName, Serializable> userProps = nodeService.getProperties(andyUserNodeRef);
|
NodeRef andyUserNodeRef = getRepositoryAuthenticationDao().getUserOrNull("Andy");
|
||||||
String passwordProp = (String)userProps.get(ContentModel.PROP_PASSWORD);
|
assertNotNull(andyUserNodeRef);
|
||||||
assertNull("Expected the password property to be null", passwordProp);
|
|
||||||
String password2Prop = (String)userProps.get(ContentModel.PROP_PASSWORD_SHA256);
|
|
||||||
assertNull("Expected the password2 property to be null", password2Prop);
|
|
||||||
String passwordHashProp = (String)userProps.get(ContentModel.PROP_PASSWORD_HASH);
|
|
||||||
assertNotNull("Expected the passwordHash property to be populated", passwordHashProp);
|
|
||||||
List<String> hashIndicatorProp = (List<String>)userProps.get(ContentModel.PROP_HASH_INDICATOR);
|
|
||||||
assertNotNull("Expected the hashIndicator property to be populated", hashIndicatorProp);
|
|
||||||
|
|
||||||
// re-generate an md4 hashed password
|
// ensure the properties are in the state we're expecting
|
||||||
MD4PasswordEncoderImpl md4PasswordEncoder = new MD4PasswordEncoderImpl();
|
Map<QName, Serializable> userProps = nodeService.getProperties(andyUserNodeRef);
|
||||||
String md4Password = md4PasswordEncoder.encodePassword("auth1", null);
|
String passwordProp = (String) userProps.get(ContentModel.PROP_PASSWORD);
|
||||||
|
assertNull("Expected the password property to be null", passwordProp);
|
||||||
|
String password2Prop = (String) userProps.get(ContentModel.PROP_PASSWORD_SHA256);
|
||||||
|
assertNull("Expected the password2 property to be null", password2Prop);
|
||||||
|
String passwordHashProp = (String) userProps.get(ContentModel.PROP_PASSWORD_HASH);
|
||||||
|
assertNotNull("Expected the passwordHash property to be populated", passwordHashProp);
|
||||||
|
List<String> hashIndicatorProp = (List<String>) userProps.get(ContentModel.PROP_HASH_INDICATOR);
|
||||||
|
assertNotNull("Expected the hashIndicator property to be populated", hashIndicatorProp);
|
||||||
|
|
||||||
// re-generate a sha256 hashed password
|
// re-generate an md4 hashed password
|
||||||
String salt = (String)userProps.get(ContentModel.PROP_SALT);
|
MD4PasswordEncoderImpl md4PasswordEncoder = new MD4PasswordEncoderImpl();
|
||||||
ShaPasswordEncoderImpl sha256PasswordEncoder = new ShaPasswordEncoderImpl(256);
|
String md4Password = md4PasswordEncoder.encodePassword("auth1", null);
|
||||||
String sha256Password = sha256PasswordEncoder.encodePassword("auth1", salt);
|
|
||||||
|
|
||||||
// change the underlying user object to represent state in previous release
|
// re-generate a sha256 hashed password
|
||||||
userProps.put(ContentModel.PROP_PASSWORD, md4Password);
|
String salt = (String) userProps.get(ContentModel.PROP_SALT);
|
||||||
userProps.put(ContentModel.PROP_PASSWORD_SHA256, sha256Password);
|
ShaPasswordEncoderImpl sha256PasswordEncoder = new ShaPasswordEncoderImpl(256);
|
||||||
userProps.remove(ContentModel.PROP_PASSWORD_HASH);
|
String sha256Password = sha256PasswordEncoder.encodePassword("auth1", salt);
|
||||||
userProps.remove(ContentModel.PROP_HASH_INDICATOR);
|
|
||||||
nodeService.setProperties(andyUserNodeRef, userProps);
|
|
||||||
|
|
||||||
// make sure the changes took effect
|
// change the underlying user object to represent state in previous release
|
||||||
Map<QName, Serializable> updatedProps = nodeService.getProperties(andyUserNodeRef);
|
userProps.put(ContentModel.PROP_PASSWORD, md4Password);
|
||||||
String usernameProp = (String)updatedProps.get(ContentModel.PROP_USER_USERNAME);
|
userProps.put(ContentModel.PROP_PASSWORD_SHA256, sha256Password);
|
||||||
assertEquals("Expected the username property to be 'Andy'", "Andy", usernameProp);
|
userProps.remove(ContentModel.PROP_PASSWORD_HASH);
|
||||||
passwordProp = (String)updatedProps.get(ContentModel.PROP_PASSWORD);
|
userProps.remove(ContentModel.PROP_HASH_INDICATOR);
|
||||||
assertNotNull("Expected the password property to be populated", passwordProp);
|
nodeService.setProperties(andyUserNodeRef, userProps);
|
||||||
password2Prop = (String)updatedProps.get(ContentModel.PROP_PASSWORD_SHA256);
|
|
||||||
assertNotNull("Expected the password2 property to be populated", password2Prop);
|
|
||||||
passwordHashProp = (String)updatedProps.get(ContentModel.PROP_PASSWORD_HASH);
|
|
||||||
assertNull("Expected the passwordHash property to be null", passwordHashProp);
|
|
||||||
hashIndicatorProp = (List<String>)updatedProps.get(ContentModel.PROP_HASH_INDICATOR);
|
|
||||||
assertNull("Expected the hashIndicator property to be null", hashIndicatorProp);
|
|
||||||
|
|
||||||
// authenticate the user
|
// make sure the changes took effect
|
||||||
authenticationComponent.clearCurrentSecurityContext();
|
Map<QName, Serializable> updatedProps = nodeService.getProperties(andyUserNodeRef);
|
||||||
pubAuthenticationService.authenticate("Andy", "auth1".toCharArray());
|
String usernameProp = (String) updatedProps.get(ContentModel.PROP_USER_USERNAME);
|
||||||
assertEquals("Andy", authenticationService.getCurrentUserName());
|
assertEquals("Expected the username property to be 'Andy'", "Andy", usernameProp);
|
||||||
|
passwordProp = (String) updatedProps.get(ContentModel.PROP_PASSWORD);
|
||||||
|
assertNotNull("Expected the password property to be populated", passwordProp);
|
||||||
|
password2Prop = (String) updatedProps.get(ContentModel.PROP_PASSWORD_SHA256);
|
||||||
|
assertNotNull("Expected the password2 property to be populated", password2Prop);
|
||||||
|
passwordHashProp = (String) updatedProps.get(ContentModel.PROP_PASSWORD_HASH);
|
||||||
|
assertNull("Expected the passwordHash property to be null", passwordHashProp);
|
||||||
|
hashIndicatorProp = (List<String>) updatedProps.get(ContentModel.PROP_HASH_INDICATOR);
|
||||||
|
assertNull("Expected the hashIndicator property to be null", hashIndicatorProp);
|
||||||
|
|
||||||
// commit the transaction to invoke the password hashing of the user
|
// authenticate the user
|
||||||
userTransaction.commit();
|
authenticationComponent.clearCurrentSecurityContext();
|
||||||
|
pubAuthenticationService.authenticate("Andy", "auth1".toCharArray());
|
||||||
|
assertEquals("Andy", authenticationService.getCurrentUserName());
|
||||||
|
|
||||||
// start another transaction and change to system user
|
// commit the transaction to invoke the password hashing of the user
|
||||||
userTransaction = transactionService.getUserTransaction();
|
userTransaction.commit();
|
||||||
userTransaction.begin();
|
|
||||||
authenticationComponent.setSystemUserAsCurrentUser();
|
|
||||||
|
|
||||||
// verify that the new properties are populated and the old ones are cleaned up
|
// start another transaction and change to system user
|
||||||
Map<QName, Serializable> upgradedProps = nodeService.getProperties(andyUserNodeRef);
|
userTransaction = transactionService.getUserTransaction();
|
||||||
passwordProp = (String)upgradedProps.get(ContentModel.PROP_PASSWORD);
|
userTransaction.begin();
|
||||||
assertNull("Expected the password property to be null", passwordProp);
|
authenticationComponent.setSystemUserAsCurrentUser();
|
||||||
password2Prop = (String)upgradedProps.get(ContentModel.PROP_PASSWORD_SHA256);
|
|
||||||
assertNull("Expected the password2 property to be null", password2Prop);
|
// verify that the new properties are populated and the old ones are cleaned up
|
||||||
passwordHashProp = (String)upgradedProps.get(ContentModel.PROP_PASSWORD_HASH);
|
Map<QName, Serializable> upgradedProps = nodeService.getProperties(andyUserNodeRef);
|
||||||
assertNotNull("Expected the passwordHash property to be populated", passwordHashProp);
|
passwordProp = (String) upgradedProps.get(ContentModel.PROP_PASSWORD);
|
||||||
hashIndicatorProp = (List<String>)upgradedProps.get(ContentModel.PROP_HASH_INDICATOR);
|
assertNull("Expected the password property to be null", passwordProp);
|
||||||
assertNotNull("Expected the hashIndicator property to be populated", hashIndicatorProp);
|
password2Prop = (String) upgradedProps.get(ContentModel.PROP_PASSWORD_SHA256);
|
||||||
assertTrue("Expected there to be a single hash indicator entry", (hashIndicatorProp.size() == 1));
|
assertNull("Expected the password2 property to be null", password2Prop);
|
||||||
String preferredEncoding = compositePasswordEncoder.getPreferredEncoding();
|
passwordHashProp = (String) upgradedProps.get(ContentModel.PROP_PASSWORD_HASH);
|
||||||
String hashEncoding = (String)hashIndicatorProp.get(0);
|
assertNotNull("Expected the passwordHash property to be populated", passwordHashProp);
|
||||||
assertEquals("Expected hash indicator to be '" + preferredEncoding + "' but it was: " + hashEncoding,
|
hashIndicatorProp = (List<String>) upgradedProps.get(ContentModel.PROP_HASH_INDICATOR);
|
||||||
|
assertNotNull("Expected the hashIndicator property to be populated", hashIndicatorProp);
|
||||||
|
assertTrue("Expected there to be a single hash indicator entry", (hashIndicatorProp.size() == 1));
|
||||||
|
String preferredEncoding = compositePasswordEncoder.getPreferredEncoding();
|
||||||
|
String hashEncoding = hashIndicatorProp.get(0);
|
||||||
|
assertEquals("Expected hash indicator to be '" + preferredEncoding + "' but it was: " + hashEncoding,
|
||||||
preferredEncoding, hashEncoding);
|
preferredEncoding, hashEncoding);
|
||||||
|
|
||||||
// delete the user and clear the security context
|
// delete the user and clear the security context
|
||||||
this.deleteAndy();
|
this.deleteAndy();
|
||||||
authenticationComponent.clearCurrentSecurityContext();
|
authenticationComponent.clearCurrentSecurityContext();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
compositePasswordEncoder.setPreferredEncoding(defaultPreferredEncoding);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For on premise the default is MD4, for cloud BCRYPT10
|
* Test password encoding with MD4 without a salt.
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
*/
|
||||||
public void testDefaultEncodingIsMD4() throws Exception
|
public void testGetsMD4Password()
|
||||||
{
|
{
|
||||||
assertNotNull(compositePasswordEncoder);
|
String defaultPreferredEncoding = compositePasswordEncoder.getPreferredEncoding();
|
||||||
assertEquals("md4", compositePasswordEncoder.getPreferredEncoding());
|
compositePasswordEncoder.setPreferredEncoding("md4");
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
try
|
||||||
* For on premise the default is MD4, get it
|
{
|
||||||
*
|
String user = "mduzer";
|
||||||
* @throws Exception
|
String rawPass = "roarPazzw0rd";
|
||||||
*/
|
dao.createUser(user, null, rawPass.toCharArray());
|
||||||
public void testGetsMD4Password() throws Exception
|
NodeRef userNodeRef = getRepositoryAuthenticationDao().getUserOrNull(user);
|
||||||
{
|
assertNotNull(userNodeRef);
|
||||||
String user = "mduzer";
|
String pass = dao.getMD4HashedPassword(user);
|
||||||
String rawPass = "roarPazzw0rd";
|
assertNotNull(pass);
|
||||||
assertEquals("md4", compositePasswordEncoder.getPreferredEncoding());
|
assertTrue(compositePasswordEncoder.matches("md4", rawPass, pass, null));
|
||||||
dao.createUser(user, null, rawPass.toCharArray());
|
|
||||||
NodeRef userNodeRef = getRepositoryAuthenticationDao().getUserOrNull(user);
|
|
||||||
assertNotNull(userNodeRef);
|
|
||||||
String pass = dao.getMD4HashedPassword(user);
|
|
||||||
assertNotNull(pass);
|
|
||||||
assertTrue(compositePasswordEncoder.matches("md4", rawPass, pass, null));
|
|
||||||
|
|
||||||
Map<QName, Serializable> properties = nodeService.getProperties(userNodeRef);
|
Map<QName, Serializable> properties = nodeService.getProperties(userNodeRef);
|
||||||
properties.remove(ContentModel.PROP_PASSWORD_HASH);
|
properties.remove(ContentModel.PROP_PASSWORD_HASH);
|
||||||
properties.remove(ContentModel.PROP_HASH_INDICATOR);
|
properties.remove(ContentModel.PROP_HASH_INDICATOR);
|
||||||
properties.remove(ContentModel.PROP_PASSWORD);
|
properties.remove(ContentModel.PROP_PASSWORD);
|
||||||
properties.remove(ContentModel.PROP_PASSWORD_SHA256);
|
properties.remove(ContentModel.PROP_PASSWORD_SHA256);
|
||||||
String encoded = compositePasswordEncoder.encode("md4",new String(rawPass), null);
|
String encoded = compositePasswordEncoder.encodePassword("md4", rawPass, List.of("md4"));
|
||||||
properties.put(ContentModel.PROP_PASSWORD, encoded);
|
properties.put(ContentModel.PROP_PASSWORD, encoded);
|
||||||
nodeService.setProperties(userNodeRef, properties);
|
nodeService.setProperties(userNodeRef, properties);
|
||||||
pass = dao.getMD4HashedPassword(user);
|
pass = dao.getMD4HashedPassword(user);
|
||||||
assertNotNull(pass);
|
assertNotNull(pass);
|
||||||
assertEquals(encoded, pass);
|
assertEquals(encoded, pass);
|
||||||
dao.deleteUser(user);
|
dao.deleteUser(user);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
compositePasswordEncoder.setPreferredEncoding(defaultPreferredEncoding);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -66,3 +66,5 @@ encryption.cipherAlgorithm=DESede/CBC/PKCS5Padding
|
|||||||
encryption.keystore.type=JCEKS
|
encryption.keystore.type=JCEKS
|
||||||
encryption.keystore.backup.type=JCEKS
|
encryption.keystore.backup.type=JCEKS
|
||||||
|
|
||||||
|
# For CI override the default hashing algorithm for password storage to save build time.
|
||||||
|
system.preferred.password.encoding=sha256
|
||||||
|
Reference in New Issue
Block a user