Merged 5.0.2-CLOUD42 (Cloud ) to 5.1.N (5.1.1)

117256 adavis: Merged 5.0.2-CLOUD (Cloud ) to 5.0.2-CLOUD42 (Cloud )
      114527 adavis: Merged BCRYPT to 5.0.2-CLOUD
         114255 gjames: createUser with a password that has already been hashed MNT-14892,RA-601


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.1.N/root@117349 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Alan Davis
2015-11-11 18:02:29 +00:00
parent 141b506072
commit 4f3ec1b547
5 changed files with 89 additions and 8 deletions

View File

@@ -86,6 +86,19 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
* @throws AlfrescoRuntimeException if the the operation is not allowed * @throws AlfrescoRuntimeException if the the operation is not allowed
*/ */
public void createUser(String userName, char[] rawPassword) throws AuthenticationException public void createUser(String userName, char[] rawPassword) throws AuthenticationException
{
createUser(userName, null, rawPassword);
}
/**
* {@inheritDoc}
* <p/>
* If enabled does nothing
*
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
@Override
public void createUser(String caseSensitiveUserName, String hashedpassword, char[] rawPassword) throws AuthenticationException
{ {
if (!allowCreateUser) if (!allowCreateUser)
{ {

View File

@@ -36,6 +36,14 @@ public interface MutableAuthenticationDao extends AuthenticationDao, SaltSource
*/ */
public void createUser(String userName, char[] rawPassword) throws AuthenticationException; public void createUser(String userName, char[] rawPassword) throws AuthenticationException;
/**
* Create a user with the given userName and password hash
* If hashedPassword is passed in then this is used, otherwise it falls back to using the rawPassword.
* It is assumed the hashed password has been encoded using system.preferred.password.encoding and doesn't use its
* own salt.
*/
public void createUser(String caseSensitiveUserName, String hashedPassword, char[] rawPassword) throws AuthenticationException;
/** /**
* Update a user's password. * Update a user's password.
*/ */

View File

@@ -78,7 +78,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
protected PolicyComponent policyComponent; protected PolicyComponent policyComponent;
private TransactionService transactionService; private TransactionService transactionService;
private CompositePasswordEncoder compositePasswordEncoder; protected CompositePasswordEncoder compositePasswordEncoder;
// note: cache is tenant-aware (if using TransctionalCache impl) // note: cache is tenant-aware (if using TransctionalCache impl)
@@ -326,6 +326,12 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
@Override @Override
public void createUser(String caseSensitiveUserName, char[] rawPassword) throws AuthenticationException public void createUser(String caseSensitiveUserName, char[] rawPassword) throws AuthenticationException
{
createUser(caseSensitiveUserName, null, rawPassword);
}
@Override
public void createUser(String caseSensitiveUserName, String hashedPassword, char[] rawPassword) throws AuthenticationException
{ {
tenantService.checkDomainUser(caseSensitiveUserName); tenantService.checkDomainUser(caseSensitiveUserName);
@@ -339,7 +345,24 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
properties.put(ContentModel.PROP_USER_USERNAME, caseSensitiveUserName); properties.put(ContentModel.PROP_USER_USERNAME, caseSensitiveUserName);
String salt = GUID.generate(); String salt = GUID.generate();
properties.put(ContentModel.PROP_SALT, salt); properties.put(ContentModel.PROP_SALT, salt);
properties.put(ContentModel.PROP_PASSWORD_HASH, compositePasswordEncoder.encodePreferred(new String(rawPassword), salt));
if (hashedPassword == null)
{
if (logger.isDebugEnabled())
{
logger.debug("Hashing raw password to "+compositePasswordEncoder.getPreferredEncoding()
+" for "+caseSensitiveUserName);
}
hashedPassword = compositePasswordEncoder.encodePreferred(new String(rawPassword), salt);
}
else
{
if (logger.isDebugEnabled())
{
logger.debug("Using hashed password for "+caseSensitiveUserName);
}
}
properties.put(ContentModel.PROP_PASSWORD_HASH, hashedPassword);
properties.put(ContentModel.PROP_HASH_INDICATOR, (Serializable) Arrays.asList(compositePasswordEncoder.getPreferredEncoding())); properties.put(ContentModel.PROP_HASH_INDICATOR, (Serializable) Arrays.asList(compositePasswordEncoder.getPreferredEncoding()));
properties.put(ContentModel.PROP_ACCOUNT_EXPIRES, Boolean.valueOf(false)); properties.put(ContentModel.PROP_ACCOUNT_EXPIRES, Boolean.valueOf(false));
properties.put(ContentModel.PROP_CREDENTIALS_EXPIRE, Boolean.valueOf(false)); properties.put(ContentModel.PROP_CREDENTIALS_EXPIRE, Boolean.valueOf(false));

View File

@@ -55,6 +55,15 @@ public class NullMutableAuthenticationDao implements MutableAuthenticationDao
throw new AlfrescoRuntimeException("Not implemented"); throw new AlfrescoRuntimeException("Not implemented");
} }
/**
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public void createUser(String caseSensitiveUserName, String hashedpassword, char[] rawPassword) throws AuthenticationException
{
throw new AlfrescoRuntimeException("Not implemented");
}
/** /**
* @throws AlfrescoRuntimeException Not implemented * @throws AlfrescoRuntimeException Not implemented
*/ */

View File

@@ -22,6 +22,8 @@ import java.io.Serializable;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
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;
@@ -1851,7 +1853,7 @@ public class AuthenticationTest extends TestCase
pubAuthenticationService.createAuthentication("Andy", "auth1".toCharArray()); pubAuthenticationService.createAuthentication("Andy", "auth1".toCharArray());
// find the node representing the Andy user and it's properties // find the node representing the Andy user and it's properties
NodeRef andyUserNodeRef = getAndyUserNodeRef(); NodeRef andyUserNodeRef = getRepositoryAuthenticationDao(). getUserOrNull("Andy");
assertNotNull(andyUserNodeRef); assertNotNull(andyUserNodeRef);
// ensure the properties are in the state we're expecting // ensure the properties are in the state we're expecting
@@ -1928,7 +1930,34 @@ public class AuthenticationTest extends TestCase
authenticationComponent.clearCurrentSecurityContext(); authenticationComponent.clearCurrentSecurityContext();
} }
private NodeRef getAndyUserNodeRef()
/**
* Tests creating a user with a Hashed password
*/
public void testCreateUserWithHashedPassword() throws Exception
{
String SOME_PASSWORD = "1 passw0rd";
List<String> encs = Arrays.asList("bcrypt10", "md4");
for (String enc : encs)
{
compositePasswordEncoder.setPreferredEncoding(enc);
String hash = compositePasswordEncoder.encodePreferred(SOME_PASSWORD,null);
assertCreateHashed(SOME_PASSWORD, hash, null, "me@you.com");
assertCreateHashed(SOME_PASSWORD, null, SOME_PASSWORD.toCharArray(), "you@me.com");
}
}
private void assertCreateHashed(String rawString, String hash, char[] rawPassword, String user)
{
dao.createUser(user, hash, rawPassword);
UserDetails userDetails = (UserDetails) dao.loadUserByUsername(user);
assertNotNull(userDetails);
assertNotNull(userDetails.getPassword());
assertTrue(compositePasswordEncoder.matches(compositePasswordEncoder.getPreferredEncoding(), rawString, userDetails.getPassword(), null));
dao.deleteUser(user);
}
private RepositoryAuthenticationDao getRepositoryAuthenticationDao()
{ {
RepositoryAuthenticationDao dao = new RepositoryAuthenticationDao(); RepositoryAuthenticationDao dao = new RepositoryAuthenticationDao();
dao.setTransactionService(transactionService); dao.setTransactionService(transactionService);
@@ -1940,8 +1969,7 @@ public class AuthenticationTest extends TestCase
dao.setPolicyComponent(policyComponent); dao.setPolicyComponent(policyComponent);
dao.setAuthenticationCache(authenticationCache); dao.setAuthenticationCache(authenticationCache);
dao.setSingletonCache(immutableSingletonCache); dao.setSingletonCache(immutableSingletonCache);
return dao;
return dao.getUserOrNull("Andy");
} }
private String getUserName(Authentication authentication) private String getUserName(Authentication authentication)