ARTEMIS-5052 hash authentication cache keys
Existing tests should suffice to validate this change.
This commit is contained in:
parent
c8f51952f4
commit
90300285c7
|
@ -18,8 +18,11 @@ package org.apache.activemq.artemis.core.security.impl;
|
|||
|
||||
import javax.security.auth.Subject;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
|
||||
|
@ -50,6 +53,7 @@ import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager3;
|
|||
import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager4;
|
||||
import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager5;
|
||||
import org.apache.activemq.artemis.spi.core.security.jaas.NoCacheLoginException;
|
||||
import org.apache.activemq.artemis.utils.ByteUtil;
|
||||
import org.apache.activemq.artemis.utils.CompositeAddress;
|
||||
import org.apache.activemq.artemis.utils.collections.ConcurrentHashSet;
|
||||
import org.apache.activemq.artemis.utils.collections.TypedProperties;
|
||||
|
@ -100,7 +104,7 @@ public class SecurityStoreImpl implements SecurityStore, HierarchicalRepositoryC
|
|||
final String managementClusterPassword,
|
||||
final NotificationService notificationService,
|
||||
final long authenticationCacheSize,
|
||||
final long authorizationCacheSize) {
|
||||
final long authorizationCacheSize) throws NoSuchAlgorithmException {
|
||||
this.securityRepository = securityRepository;
|
||||
this.securityManager = securityManager;
|
||||
this.securityEnabled = securityEnabled;
|
||||
|
@ -185,7 +189,8 @@ public class SecurityStoreImpl implements SecurityStore, HierarchicalRepositoryC
|
|||
boolean check = true;
|
||||
|
||||
Subject subject = null;
|
||||
Pair<Boolean, Subject> cacheEntry = getAuthenticationCacheEntry(user, password, connection);
|
||||
String authnCacheKey = createAuthenticationCacheKey(user, password, connection);
|
||||
Pair<Boolean, Subject> cacheEntry = getAuthenticationCacheEntry(authnCacheKey);
|
||||
if (cacheEntry != null) {
|
||||
if (!cacheEntry.getA()) {
|
||||
// cached authentication failed previously so don't check again
|
||||
|
@ -212,7 +217,7 @@ public class SecurityStoreImpl implements SecurityStore, HierarchicalRepositoryC
|
|||
if (securityManager instanceof ActiveMQSecurityManager5) {
|
||||
try {
|
||||
subject = ((ActiveMQSecurityManager5) securityManager).authenticate(user, password, connection, securityDomain);
|
||||
putAuthenticationCacheEntry(user, password, connection, subject);
|
||||
putAuthenticationCacheEntry(authnCacheKey, subject);
|
||||
validatedUser = getUserFromSubject(subject);
|
||||
} catch (NoCacheLoginException e) {
|
||||
handleNoCacheLoginException(e);
|
||||
|
@ -435,7 +440,8 @@ public class SecurityStoreImpl implements SecurityStore, HierarchicalRepositoryC
|
|||
* @return the authenticated Subject with all associated role principals
|
||||
*/
|
||||
private Subject getSubjectForAuthorization(SecurityAuth auth, ActiveMQSecurityManager5 securityManager) {
|
||||
Pair<Boolean, Subject> cached = getAuthenticationCacheEntry(auth.getUsername(), auth.getPassword(), auth.getRemotingConnection());
|
||||
String authnCacheKey = createAuthenticationCacheKey(auth.getUsername(), auth.getPassword(), auth.getRemotingConnection());
|
||||
Pair<Boolean, Subject> cached = getAuthenticationCacheEntry(authnCacheKey);
|
||||
|
||||
if (cached == null && auth.getUsername() == null && auth.getPassword() == null && auth.getRemotingConnection() instanceof ManagementRemotingConnection) {
|
||||
AccessControlContext accessControlContext = AccessController.getContext();
|
||||
|
@ -451,7 +457,7 @@ public class SecurityStoreImpl implements SecurityStore, HierarchicalRepositoryC
|
|||
if (cached == null) {
|
||||
try {
|
||||
Subject subject = securityManager.authenticate(auth.getUsername(), auth.getPassword(), auth.getRemotingConnection(), auth.getSecurityDomain());
|
||||
putAuthenticationCacheEntry(auth.getUsername(), auth.getPassword(), auth.getRemotingConnection(), subject);
|
||||
putAuthenticationCacheEntry(authnCacheKey, subject);
|
||||
return subject;
|
||||
} catch (NoCacheLoginException e) {
|
||||
handleNoCacheLoginException(e);
|
||||
|
@ -465,22 +471,17 @@ public class SecurityStoreImpl implements SecurityStore, HierarchicalRepositoryC
|
|||
logger.debug("Skipping authentication cache due to exception: {}", e.getMessage());
|
||||
}
|
||||
|
||||
private void putAuthenticationCacheEntry(String user,
|
||||
String password,
|
||||
RemotingConnection connection,
|
||||
Subject subject) {
|
||||
private void putAuthenticationCacheEntry(String key, Subject subject) {
|
||||
if (authenticationCache != null) {
|
||||
authenticationCache.put(createAuthenticationCacheKey(user, password, connection), new Pair<>(subject != null, subject));
|
||||
authenticationCache.put(key, new Pair<>(subject != null, subject));
|
||||
}
|
||||
}
|
||||
|
||||
private Pair<Boolean, Subject> getAuthenticationCacheEntry(String user,
|
||||
String password,
|
||||
RemotingConnection connection) {
|
||||
private Pair<Boolean, Subject> getAuthenticationCacheEntry(String key) {
|
||||
if (authenticationCache == null) {
|
||||
return null;
|
||||
} else {
|
||||
return authenticationCache.getIfPresent(createAuthenticationCacheKey(user, password, connection));
|
||||
return authenticationCache.getIfPresent(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -538,7 +539,11 @@ public class SecurityStoreImpl implements SecurityStore, HierarchicalRepositoryC
|
|||
}
|
||||
|
||||
private String createAuthenticationCacheKey(String username, String password, RemotingConnection connection) {
|
||||
return username + password + CertificateUtil.getCertSubjectDN(connection);
|
||||
try {
|
||||
return ByteUtil.bytesToHex(MessageDigest.getInstance("SHA-256").digest((username + password + CertificateUtil.getCertSubjectDN(connection)).getBytes(StandardCharsets.UTF_8)));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String createAuthorizationCacheKey(String user, CheckType checkType) {
|
||||
|
|
Loading…
Reference in New Issue