This is an automated email from the ASF dual-hosted git repository.

clebertsuconic pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/artemis.git


The following commit(s) were added to refs/heads/main by this push:
     new 9054a60d2b ARTEMIS-6037 refactor handling of cluster credentials
9054a60d2b is described below

commit 9054a60d2bd8ef998daf1879da37eb36a563d05b
Author: Justin Bertram <[email protected]>
AuthorDate: Tue Apr 28 08:27:27 2026 -0500

    ARTEMIS-6037 refactor handling of cluster credentials
---
 .../core/security/impl/SecurityStoreImpl.java      |  64 +-
 .../artemis/core/server/ActiveMQServerLogger.java  |   4 +-
 .../core/server/cluster/ClusterConnection.java     |   7 -
 .../core/server/cluster/ClusterController.java     |  15 +-
 .../core/server/cluster/ClusterManager.java        |   2 +-
 .../server/cluster/impl/ClusterConnectionImpl.java |   5 -
 .../core/server/impl/ActiveMQServerImpl.java       |   2 +-
 .../core/security/impl/SecurityStoreImplTest.java  | 683 +++++++--------------
 docs/user-manual/_bridge-credentials-note.adoc     |   6 +
 docs/user-manual/clusters.adoc                     |  10 +-
 docs/user-manual/core-bridges.adoc                 |  12 +-
 docs/user-manual/versions.adoc                     |  19 +
 .../cluster/ClusterControllerDirectAuthTest.java   | 106 ++++
 .../cluster/topology/TopologyClusterTestBase.java  |  17 +-
 ...urityManagementWithConfiguredAdminUserTest.java |   2 +-
 ...rityManagementWithDefaultConfigurationTest.java |   2 +-
 .../integration/server/ScaleDown3NodeTest.java     |  61 +-
 .../servers/bridgeTransfer/serverA/broker.xml      |   2 +
 .../ClusteredLargeMessageTest.java                 |   4 +-
 19 files changed, 479 insertions(+), 544 deletions(-)

diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
index 0ba198aaa5..1b3822a61a 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
@@ -29,6 +29,7 @@ import java.util.stream.Collectors;
 
 import com.github.benmanes.caffeine.cache.Cache;
 import com.github.benmanes.caffeine.cache.Caffeine;
+import org.apache.activemq.artemis.api.core.ActiveMQSecurityException;
 import org.apache.activemq.artemis.api.core.Pair;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
@@ -63,6 +64,8 @@ import 
org.apache.activemq.artemis.utils.sm.SecurityManagerShim;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static 
org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration.getDefaultClusterPassword;
+import static 
org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration.getDefaultClusterUser;
 import static 
org.apache.activemq.artemis.utils.CertificateUtil.CERT_SUBJECT_DN_UNAVAILABLE;
 
 /**
@@ -113,7 +116,7 @@ public class SecurityStoreImpl implements SecurityStore, 
HierarchicalRepositoryC
                             final String managementClusterPassword,
                             final NotificationService notificationService,
                             final long authenticationCacheSize,
-                            final long authorizationCacheSize) throws 
NoSuchAlgorithmException {
+                            final long authorizationCacheSize) {
       this.securityRepository = securityRepository;
       this.securityManager = securityManager;
       this.securityEnabled = securityEnabled;
@@ -178,24 +181,10 @@ public class SecurityStoreImpl implements SecurityStore, 
HierarchicalRepositoryC
                               RemotingConnection connection,
                               String securityDomain) throws Exception {
       if (securityEnabled) {
-
-         if (managementClusterUser.equals(user)) {
-            logger.trace("Authenticating cluster admin user");
-
-            /*
-             * The special user cluster user is used for creating sessions 
that replicate management
-             * operation between nodes
-             */
-            if (!managementClusterPassword.equals(password)) {
-               AUTHENTICATION_FAILURE_COUNT_UPDATER.incrementAndGet(this);
-               throw 
ActiveMQMessageBundle.BUNDLE.unableToValidateClusterUser(user);
-            } else {
-               AUTHENTICATION_SUCCESS_COUNT_UPDATER.incrementAndGet(this);
-               return managementClusterUser;
-            }
+         String validatedUser = handleClusterAuthentication(user, password, 
connection);
+         if (validatedUser != null) {
+            return validatedUser;
          }
-
-         String validatedUser = null;
          boolean userIsValid = false;
          boolean check = true;
 
@@ -305,10 +294,12 @@ public class SecurityStoreImpl implements SecurityStore, 
HierarchicalRepositoryC
          return true;
       }
 
-      // bypass permission checks for management cluster user
       String user = session.getUsername();
-      if (managementClusterUser.equals(user) && 
session.getPassword().equals(managementClusterPassword)) {
+      ClusterCredentialsCheckResult checkResult = 
checkClusterCredentials(user, session.getPassword());
+      if (checkResult == ClusterCredentialsCheckResult.VALID) {
          return true;
+      } else if (checkResult == ClusterCredentialsCheckResult.INVALID) {
+         return false;
       }
 
       // Special case: detect authentication failure for 
ActiveMQSecurityManager5
@@ -384,6 +375,39 @@ public class SecurityStoreImpl implements SecurityStore, 
HierarchicalRepositoryC
       }
    }
 
+   private String handleClusterAuthentication(String user, String password, 
RemotingConnection connection) throws ActiveMQSecurityException {
+      ClusterCredentialsCheckResult checkResult = 
checkClusterCredentials(user, password);
+
+      if (checkResult == ClusterCredentialsCheckResult.VALID) {
+         AUTHENTICATION_SUCCESS_COUNT_UPDATER.incrementAndGet(this);
+         return user;
+      } else if (checkResult == ClusterCredentialsCheckResult.INVALID) {
+         AUTHENTICATION_FAILURE_COUNT_UPDATER.incrementAndGet(this);
+         throw ActiveMQMessageBundle.BUNDLE.unableToValidateUser(connection == 
null ? "null" : connection.getRemoteAddress(), user, null);
+      } else {
+         return null;
+      }
+   }
+
+   private ClusterCredentialsCheckResult checkClusterCredentials(String user, 
String password) {
+      if ((getDefaultClusterUser().equals(user) && 
getDefaultClusterPassword().equals(password))) {
+         // reject default cluster credentials
+         return ClusterCredentialsCheckResult.INVALID;
+      } else if (managementClusterUser.equals(user) && 
!managementClusterPassword.equals(password)) {
+         // reject if username is right, but password is wrong
+         return ClusterCredentialsCheckResult.INVALID;
+      } else if (managementClusterUser.equals(user) && 
managementClusterPassword.equals(password)) {
+         // accept if both user & password are right
+         return ClusterCredentialsCheckResult.VALID;
+      } else {
+         return ClusterCredentialsCheckResult.IGNORE;
+      }
+   }
+
+   enum ClusterCredentialsCheckResult {
+      VALID, INVALID, IGNORE
+   }
+
    @Override
    public void check(final SimpleString address,
                      final SimpleString queue,
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
index 93ead521c2..1f69606a56 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
@@ -341,8 +341,8 @@ public interface ActiveMQServerLogger {
    @LogMessage(id = 222006, value = "Binding already exists with name {}, 
divert will not be deployed", level = LogMessage.Level.WARN)
    void divertBindingAlreadyExists(SimpleString bindingName);
 
-   @LogMessage(id = 222007, value = "Security risk! Apache Artemis is running 
with the default cluster admin user and default password. Please see the 
cluster chapter in the Artemis User Guide for instructions on how to change 
this.", level = LogMessage.Level.WARN)
-   void clusterSecurityRisk();
+   @LogMessage(id = 222007, value = "Apache Artemis is running with the 
default cluster user and password. Any connection using these credentials will 
be rejected. Please see the cluster chapter in the Artemis User Guide for 
instructions on how to change this.", level = LogMessage.Level.WARN)
+   void defaultClusterCredentialsInUse();
 
    @LogMessage(id = 222008, value = "unable to restart server, please kill and 
restart manually", level = LogMessage.Level.WARN)
    void serverRestartWarning(Exception e);
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterConnection.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterConnection.java
index 28e53ee7fe..6f076bb0ca 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterConnection.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterConnection.java
@@ -74,13 +74,6 @@ public interface ClusterConnection extends 
ActiveMQComponent, ClusterTopologyLis
 
    boolean isNodeActive(String id);
 
-   /**
-    * Verifies whether user and password match the ones configured for this 
ClusterConnection.
-    *
-    * @return {@code true} if username and password match, {@code false} 
otherwise
-    */
-   boolean verify(String clusterUser, String clusterPassword);
-
    void removeRecord(String targetNodeID);
 
    void disconnectRecord(String targetNodeID);
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterController.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterController.java
index 00c725b78b..fcc0d77ae2 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterController.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterController.java
@@ -407,11 +407,20 @@ public class ClusterController implements 
ActiveMQComponent {
 
                ClusterConnectMessage msg = (ClusterConnectMessage) packet;
 
-               if (server.getConfiguration().isSecurityEnabled() && 
!clusterConnection.verify(msg.getClusterUser(), msg.getClusterPassword())) {
-                  clusterChannel.send(new ClusterConnectReplyMessage(false));
-               } else {
+               boolean userIsValid = false;
+               try {
+                  server.validateUser(msg.getClusterUser(), 
msg.getClusterPassword(), null, null);
+                  userIsValid = true;
+               } catch (Exception e) {
+                  // cluster user isn't valid
+                  logger.debug("Failed to validate user: {}", 
msg.getClusterUser(), e);
+               }
+
+               if (userIsValid) {
                   authorized = true;
                   clusterChannel.send(new ClusterConnectReplyMessage(true));
+               } else {
+                  clusterChannel.send(new ClusterConnectReplyMessage(false));
                }
             }
          } else {
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterManager.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterManager.java
index 1914b77c6b..4661afac34 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterManager.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterManager.java
@@ -506,7 +506,7 @@ public class ClusterManager implements ActiveMQComponent {
          if (packet.getType() == PacketImpl.EXCEPTION) {
             ActiveMQExceptionMessage msg = (ActiveMQExceptionMessage) packet;
             final ActiveMQException exception = msg.getException();
-            if (exception.getType() == 
ActiveMQExceptionType.CLUSTER_SECURITY_EXCEPTION) {
+            if (exception.getType() == 
ActiveMQExceptionType.CLUSTER_SECURITY_EXCEPTION || exception.getType() == 
ActiveMQExceptionType.SECURITY_EXCEPTION) {
                
ActiveMQServerLogger.LOGGER.clusterManagerAuthenticationError(exception.getMessage());
                executor.execute(() -> {
                   try {
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/ClusterConnectionImpl.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/ClusterConnectionImpl.java
index bfe893926c..e00f09d7af 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/ClusterConnectionImpl.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/ClusterConnectionImpl.java
@@ -1769,11 +1769,6 @@ public final class ClusterConnectionImpl implements 
ClusterConnection, AfterConn
       }
    }
 
-   @Override
-   public boolean verify(String clusterUser0, String clusterPassword0) {
-      return clusterUser.equals(clusterUser0) && 
clusterPassword.equals(clusterPassword0);
-   }
-
    @Override
    public void removeRecord(String targetNodeID) {
       logger.debug("Removing record for: {}", targetNodeID);
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
index 3ae92b1a1b..ae9819bc64 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
@@ -3401,7 +3401,7 @@ public class ActiveMQServerImpl implements ActiveMQServer 
{
       storageManager = createStorageManager();
 
       if (!configuration.getClusterConfigurations().isEmpty() && 
ActiveMQDefaultConfiguration.getDefaultClusterUser().equals(configuration.getClusterUser())
 && 
ActiveMQDefaultConfiguration.getDefaultClusterPassword().equals(configuration.getClusterPassword()))
 {
-         ActiveMQServerLogger.LOGGER.clusterSecurityRisk();
+         ActiveMQServerLogger.LOGGER.defaultClusterCredentialsInUse();
       }
 
       securityStore = new SecurityStoreImpl(securityRepository, 
securityManager, configuration.getSecurityInvalidationInterval(), 
configuration.isSecurityEnabled(), configuration.getClusterUser(), 
configuration.getClusterPassword(), managementService, 
configuration.getAuthenticationCacheSize(), 
configuration.getAuthorizationCacheSize());
diff --git 
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImplTest.java
 
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImplTest.java
index 9aea05f044..915ea76b03 100644
--- 
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImplTest.java
+++ 
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImplTest.java
@@ -21,6 +21,7 @@ import java.security.Principal;
 import java.util.Set;
 import java.util.concurrent.Callable;
 
+import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
 import org.apache.activemq.artemis.api.core.ActiveMQSecurityException;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
@@ -44,6 +45,8 @@ import org.mockito.ArgumentCaptor;
 import org.mockito.ArgumentMatchers;
 import org.mockito.Mockito;
 
+import static 
org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration.getDefaultClusterPassword;
+import static 
org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration.getDefaultClusterUser;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -53,15 +56,13 @@ import static org.junit.jupiter.api.Assertions.fail;
 
 public class SecurityStoreImplTest {
 
-   final ActiveMQSecurityManager5 securityManager = new 
ActiveMQSecurityManager5() {
+   final ActiveMQSecurityManager5 permitAll = new ActiveMQSecurityManager5() {
       @Override
       public Subject authenticate(String user,
                                   String password,
                                   RemotingConnection remotingConnection,
                                   String securityDomain) {
-         Subject subject = new Subject();
-         subject.getPrincipals().add(new UserPrincipal(user));
-         return subject;
+         return getSubject(user);
       }
 
       @Override
@@ -69,6 +70,31 @@ public class SecurityStoreImplTest {
          return true;
       }
 
+      @Override
+      public boolean validateUser(String user, String password) {
+         return true;
+      }
+
+      @Override
+      public boolean validateUserAndRole(String user, String password, 
Set<Role> roles, CheckType checkType) {
+         return true;
+      }
+   };
+
+   final ActiveMQSecurityManager5 denyAll = new ActiveMQSecurityManager5() {
+      @Override
+      public Subject authenticate(String user,
+                                  String password,
+                                  RemotingConnection remotingConnection,
+                                  String securityDomain) {
+         return null;
+      }
+
+      @Override
+      public boolean authorize(Subject subject, Set<Role> roles, CheckType 
checkType, String address) {
+         return false;
+      }
+
       @Override
       public boolean validateUser(String user, String password) {
          return false;
@@ -115,41 +141,21 @@ public class SecurityStoreImplTest {
    @Test
    public void zeroCacheSizeTest() throws Exception {
       final String user = RandomUtil.randomUUIDString();
-      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), securityManager, 999, true, "", null, null, 
0, 0);
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, "", null, null, 0, 0);
       assertNull(securityStore.getAuthenticationCache());
       assertEquals(user, securityStore.authenticate(user, 
RandomUtil.randomUUIDString(), null));
       assertEquals(0, securityStore.getAuthenticationCacheSize());
       securityStore.invalidateAuthenticationCache(); // ensure this doesn't 
throw an NPE
 
       assertNull(securityStore.getAuthorizationCache());
-      securityStore.check(RandomUtil.randomUUIDSimpleString(), CheckType.SEND, 
new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return RandomUtil.randomUUIDString();
-         }
-
-         @Override
-         public String getPassword() {
-            return RandomUtil.randomUUIDString();
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return null;
-         }
-
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      });
+      securityStore.check(RandomUtil.randomUUIDSimpleString(), CheckType.SEND, 
getSecurityAuth(RandomUtil.randomUUIDString(), RandomUtil.randomUUIDString()));
       assertEquals(0, securityStore.getAuthorizationCacheSize());
       securityStore.invalidateAuthorizationCache(); // ensure this doesn't 
throw an NPE
    }
 
    @Test
    public void getCaller() throws Exception {
-      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), securityManager, 999, true, "", null, null, 
0, 0);
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, "", null, null, 0, 0);
 
       assertNull(securityStore.getCaller(null, null));
       assertEquals("joe", securityStore.getCaller("joe", null));
@@ -227,7 +233,7 @@ public class SecurityStoreImplTest {
    @Test
    public void testCacheAlgorithm() throws Exception {
       final String user = RandomUtil.randomUUIDString();
-      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), securityManager, 999, true, "", null, null, 
0, 0);
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, "", null, null, 0, 0);
       try (AssertionLoggerHandler handler = new AssertionLoggerHandler()) {
          securityStore.createAuthenticationCacheKey(user, 
RandomUtil.randomUUIDString(), null);
          assertFalse(handler.findText("AMQ224163"));
@@ -236,30 +242,8 @@ public class SecurityStoreImplTest {
 
    @Test
    public void testHasPermissionSecurityDisabled() throws Exception {
-      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), securityManager, 999, false, "", null, null, 
0, 0);
-
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return "user";
-         }
-
-         @Override
-         public String getPassword() {
-            return "pass";
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return null;
-         }
-
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
-
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), denyAll, 999, false, "", null, null, 0, 0);
+      SecurityAuth session = getSecurityAuth("user", "pass");
       assertTrue(securityStore.hasPermission(SimpleString.of("test.address"), 
null, CheckType.SEND, session));
    }
 
@@ -267,30 +251,8 @@ public class SecurityStoreImplTest {
    public void testHasPermissionClusterUser() throws Exception {
       final String clusterUser = "clusterUser";
       final String clusterPassword = "clusterPassword";
-      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), securityManager, 999, true, clusterUser, 
clusterPassword, null, 0, 0);
-
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return clusterUser;
-         }
-
-         @Override
-         public String getPassword() {
-            return clusterPassword;
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return null;
-         }
-
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
-
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, clusterUser, 
clusterPassword, null, 0, 0);
+      SecurityAuth session = getSecurityAuth(clusterUser, clusterPassword);
       assertTrue(securityStore.hasPermission(SimpleString.of("test.address"), 
null, CheckType.SEND, session));
    }
 
@@ -320,27 +282,7 @@ public class SecurityStoreImplTest {
 
       SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), nullSubjectManager, 999, true, "", null, 
null, 0, 0);
 
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return "user";
-         }
-
-         @Override
-         public String getPassword() {
-            return "pass";
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return Mockito.mock(RemotingConnection.class);
-         }
-
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth("user", "pass");
 
       try {
          securityStore.hasPermission(SimpleString.of("test.address"), null, 
CheckType.SEND, session);
@@ -353,32 +295,13 @@ public class SecurityStoreImplTest {
 
    @Test
    public void testHasPermissionAuthorized() throws Exception {
-      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), securityManager, 999, true, "", null, null, 
10, 10);
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, "", null, null, 10, 10);
 
       final String user = "authorizedUser";
-      securityStore.authenticate(user, "password", 
Mockito.mock(RemotingConnection.class));
-
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return user;
-         }
+      final String password = "password";
+      securityStore.authenticate(user, password, 
Mockito.mock(RemotingConnection.class));
 
-         @Override
-         public String getPassword() {
-            return "password";
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return Mockito.mock(RemotingConnection.class);
-         }
-
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth(user, password);
 
       assertTrue(securityStore.hasPermission(SimpleString.of("test.address"), 
null, CheckType.SEND, session));
    }
@@ -388,9 +311,7 @@ public class SecurityStoreImplTest {
       ActiveMQSecurityManager5 denyingManager = new ActiveMQSecurityManager5() 
{
          @Override
          public Subject authenticate(String user, String password, 
RemotingConnection remotingConnection, String securityDomain) {
-            Subject subject = new Subject();
-            subject.getPrincipals().add(new UserPrincipal(user));
-            return subject;
+            return getSubject(user);
          }
 
          @Override
@@ -412,62 +333,23 @@ public class SecurityStoreImplTest {
       SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), denyingManager, 999, true, "", null, null, 
10, 10);
 
       final String user = "unauthorizedUser";
-      securityStore.authenticate(user, "password", 
Mockito.mock(RemotingConnection.class));
+      final String password = "password";
+      securityStore.authenticate(user, password, 
Mockito.mock(RemotingConnection.class));
 
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return user;
-         }
-
-         @Override
-         public String getPassword() {
-            return "password";
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return Mockito.mock(RemotingConnection.class);
-         }
-
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth(user, password);
 
       assertFalse(securityStore.hasPermission(SimpleString.of("test.address"), 
null, CheckType.SEND, session));
    }
 
    @Test
    public void testHasPermissionUsesCache() throws Exception {
-      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), securityManager, 999, true, "", null, null, 
10, 10);
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, "", null, null, 10, 10);
 
       final String user = "cachedUser";
-      RemotingConnection connection = Mockito.mock(RemotingConnection.class);
-      securityStore.authenticate(user, "password", connection);
-
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return user;
-         }
-
-         @Override
-         public String getPassword() {
-            return "password";
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return connection;
-         }
+      final String password = "password";
+      securityStore.authenticate(user, password, 
Mockito.mock(RemotingConnection.class));
 
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth(user, password);
 
       SimpleString address = SimpleString.of("test.address");
 
@@ -485,9 +367,7 @@ public class SecurityStoreImplTest {
       ActiveMQSecurityManager5 denyingManager = new ActiveMQSecurityManager5() 
{
          @Override
          public Subject authenticate(String user, String password, 
RemotingConnection remotingConnection, String securityDomain) {
-            Subject subject = new Subject();
-            subject.getPrincipals().add(new UserPrincipal(user));
-            return subject;
+            return getSubject(user);
          }
 
          @Override
@@ -511,27 +391,7 @@ public class SecurityStoreImplTest {
       final String user = "deniedUser";
       securityStore.authenticate(user, "password", 
Mockito.mock(RemotingConnection.class));
 
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return user;
-         }
-
-         @Override
-         public String getPassword() {
-            return "password";
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return Mockito.mock(RemotingConnection.class);
-         }
-
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth("user", "password");
 
       // hasPermission should return false without incrementing failure counter
       long initialFailureCount = securityStore.getAuthorizationFailureCount();
@@ -541,29 +401,9 @@ public class SecurityStoreImplTest {
 
    @Test
    public void testCheckSecurityDisabled() throws Exception {
-      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), securityManager, 999, false, "", null, null, 
0, 0);
-
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return "user";
-         }
-
-         @Override
-         public String getPassword() {
-            return "pass";
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return null;
-         }
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, false, "", null, null, 0, 0);
 
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth("user", "password");
 
       // Should not throw exception when security is disabled
       securityStore.check(SimpleString.of("test.address"), null, 
CheckType.SEND, session);
@@ -573,33 +413,13 @@ public class SecurityStoreImplTest {
 
    @Test
    public void testCheckAuthorizedIncrementsSuccessCounter() throws Exception {
-      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), securityManager, 999, true, "", null, null, 
10, 10);
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, "", null, null, 10, 10);
 
       final String user = "authorizedUser";
-      RemotingConnection connection = Mockito.mock(RemotingConnection.class);
-      securityStore.authenticate(user, "password", connection);
-
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return user;
-         }
-
-         @Override
-         public String getPassword() {
-            return "password";
-         }
+      final String password = "password";
+      securityStore.authenticate(user, password, 
Mockito.mock(RemotingConnection.class));
 
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return connection;
-         }
-
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth(user, password);
 
       long initialSuccessCount = securityStore.getAuthorizationSuccessCount();
       securityStore.check(SimpleString.of("test.address"), null, 
CheckType.SEND, session);
@@ -612,9 +432,7 @@ public class SecurityStoreImplTest {
       ActiveMQSecurityManager5 denyingManager = new ActiveMQSecurityManager5() 
{
          @Override
          public Subject authenticate(String user, String password, 
RemotingConnection remotingConnection, String securityDomain) {
-            Subject subject = new Subject();
-            subject.getPrincipals().add(new UserPrincipal(user));
-            return subject;
+            return getSubject(user);
          }
 
          @Override
@@ -636,30 +454,11 @@ public class SecurityStoreImplTest {
       SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), denyingManager, 999, true, "", null, null, 
10, 10);
 
       final String user = "deniedUser";
+      final String password = "password";
       RemotingConnection connection = Mockito.mock(RemotingConnection.class);
-      securityStore.authenticate(user, "password", connection);
-
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return user;
-         }
-
-         @Override
-         public String getPassword() {
-            return "password";
-         }
+      securityStore.authenticate(user, password, connection);
 
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return connection;
-         }
-
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth(user, password);
 
       SimpleString address = SimpleString.of("test.address");
       long initialFailureCount = securityStore.getAuthorizationFailureCount();
@@ -681,9 +480,7 @@ public class SecurityStoreImplTest {
       ActiveMQSecurityManager5 denyingManager = new ActiveMQSecurityManager5() 
{
          @Override
          public Subject authenticate(String user, String password, 
RemotingConnection remotingConnection, String securityDomain) {
-            Subject subject = new Subject();
-            subject.getPrincipals().add(new UserPrincipal(user));
-            return subject;
+            return getSubject(user);
          }
 
          @Override
@@ -705,30 +502,10 @@ public class SecurityStoreImplTest {
       SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), denyingManager, 999, true, "", null, null, 
10, 10);
 
       final String user = "deniedUser";
-      RemotingConnection connection = Mockito.mock(RemotingConnection.class);
-      securityStore.authenticate(user, "password", connection);
+      final String password = "password";
+      securityStore.authenticate(user, password, 
Mockito.mock(RemotingConnection.class));
 
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return user;
-         }
-
-         @Override
-         public String getPassword() {
-            return "password";
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return connection;
-         }
-
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth(user, password);
 
       SimpleString address = SimpleString.of("test.address");
       SimpleString queue = SimpleString.of("test.queue");
@@ -749,29 +526,9 @@ public class SecurityStoreImplTest {
    public void testCheckDelegatesClusterUserBypass() throws Exception {
       final String clusterUser = "clusterUser";
       final String clusterPassword = "clusterPassword";
-      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), securityManager, 999, true, clusterUser, 
clusterPassword, null, 0, 0);
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, clusterUser, 
clusterPassword, null, 0, 0);
 
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return clusterUser;
-         }
-
-         @Override
-         public String getPassword() {
-            return clusterPassword;
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return null;
-         }
-
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth(clusterUser, clusterPassword);
 
       long initialSuccessCount = securityStore.getAuthorizationSuccessCount();
       securityStore.check(SimpleString.of("test.address"), null, 
CheckType.SEND, session);
@@ -780,33 +537,13 @@ public class SecurityStoreImplTest {
 
    @Test
    public void testCheckCachesSuccessfulAuthorization() throws Exception {
-      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), securityManager, 999, true, "", null, null, 
10, 10);
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, "", null, null, 10, 10);
 
       final String user = "cachedUser";
-      RemotingConnection connection = Mockito.mock(RemotingConnection.class);
-      securityStore.authenticate(user, "password", connection);
-
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return user;
-         }
-
-         @Override
-         public String getPassword() {
-            return "password";
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return connection;
-         }
+      final String password = "password";
+      securityStore.authenticate(user, password, 
Mockito.mock(RemotingConnection.class));
 
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth(user, password);
 
       SimpleString address = SimpleString.of("test.address");
 
@@ -824,9 +561,7 @@ public class SecurityStoreImplTest {
       ActiveMQSecurityManager5 denyingManager = new ActiveMQSecurityManager5() 
{
          @Override
          public Subject authenticate(String user, String password, 
RemotingConnection remotingConnection, String securityDomain) {
-            Subject subject = new Subject();
-            subject.getPrincipals().add(new UserPrincipal(user));
-            return subject;
+            return getSubject(user);
          }
 
          @Override
@@ -849,31 +584,10 @@ public class SecurityStoreImplTest {
       SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), denyingManager, 999, true, "", null, 
notificationService, 10, 10);
 
       final String user = "deniedUser";
-      RemotingConnection connection = Mockito.mock(RemotingConnection.class);
-      Mockito.when(connection.getSubject()).thenReturn(new Subject());
-      securityStore.authenticate(user, "password", connection);
-
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return user;
-         }
-
-         @Override
-         public String getPassword() {
-            return "password";
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return connection;
-         }
+      final String password = "password";
+      securityStore.authenticate(user, password, 
Mockito.mock(RemotingConnection.class));
 
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth(user, password);
 
       SimpleString address = SimpleString.of("test.address");
 
@@ -900,9 +614,7 @@ public class SecurityStoreImplTest {
       ActiveMQSecurityManager5 denyingManager = new ActiveMQSecurityManager5() 
{
          @Override
          public Subject authenticate(String user, String password, 
RemotingConnection remotingConnection, String securityDomain) {
-            Subject subject = new Subject();
-            subject.getPrincipals().add(new UserPrincipal(user));
-            return subject;
+            return getSubject(user);
          }
 
          @Override
@@ -925,31 +637,10 @@ public class SecurityStoreImplTest {
       SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), denyingManager, 999, true, "", null, 
notificationService, 10, 10);
 
       final String user = "deniedUser";
-      RemotingConnection connection = Mockito.mock(RemotingConnection.class);
-      Mockito.when(connection.getSubject()).thenReturn(new Subject());
-      securityStore.authenticate(user, "password", connection);
-
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return user;
-         }
-
-         @Override
-         public String getPassword() {
-            return "password";
-         }
+      final String password = "password";
+      securityStore.authenticate(user, password, 
Mockito.mock(RemotingConnection.class));
 
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return connection;
-         }
-
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth(user, password);
 
       SimpleString address = SimpleString.of("test.address");
 
@@ -974,9 +665,7 @@ public class SecurityStoreImplTest {
       ActiveMQSecurityManager5 denyingManager = new ActiveMQSecurityManager5() 
{
          @Override
          public Subject authenticate(String user, String password, 
RemotingConnection remotingConnection, String securityDomain) {
-            Subject subject = new Subject();
-            subject.getPrincipals().add(new UserPrincipal(user));
-            return subject;
+            return getSubject(user);
          }
 
          @Override
@@ -999,31 +688,10 @@ public class SecurityStoreImplTest {
       SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), denyingManager, 999, true, "", null, null, 
10, 10);
 
       final String user = "deniedUser";
-      RemotingConnection connection = Mockito.mock(RemotingConnection.class);
-      Mockito.when(connection.getSubject()).thenReturn(new Subject());
-      securityStore.authenticate(user, "password", connection);
-
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return user;
-         }
+      final String password = "password";
+      securityStore.authenticate(user, password, 
Mockito.mock(RemotingConnection.class));
 
-         @Override
-         public String getPassword() {
-            return "password";
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return connection;
-         }
-
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth(user, password);
 
       try {
          securityStore.check(SimpleString.of("test.address"), null, 
CheckType.SEND, session);
@@ -1034,14 +702,18 @@ public class SecurityStoreImplTest {
       }
    }
 
+   private static Subject getSubject(String user) {
+      Subject subject = new Subject();
+      subject.getPrincipals().add(new UserPrincipal(user));
+      return subject;
+   }
+
    @Test
    public void testHasPermissionDoesNotSendNotification() throws Exception {
       ActiveMQSecurityManager5 denyingManager = new ActiveMQSecurityManager5() 
{
          @Override
          public Subject authenticate(String user, String password, 
RemotingConnection remotingConnection, String securityDomain) {
-            Subject subject = new Subject();
-            subject.getPrincipals().add(new UserPrincipal(user));
-            return subject;
+            return getSubject(user);
          }
 
          @Override
@@ -1064,30 +736,10 @@ public class SecurityStoreImplTest {
       SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), denyingManager, 999, true, "", null, 
notificationService, 10, 10);
 
       final String user = "deniedUser";
-      RemotingConnection connection = Mockito.mock(RemotingConnection.class);
-      securityStore.authenticate(user, "password", connection);
-
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return user;
-         }
-
-         @Override
-         public String getPassword() {
-            return "password";
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return connection;
-         }
+      final String password = "password";
+      securityStore.authenticate(user, password, 
Mockito.mock(RemotingConnection.class));
 
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth(user, password);
 
       // Call hasPermission - should return false
       assertFalse(securityStore.hasPermission(SimpleString.of("test.address"), 
null, CheckType.SEND, session));
@@ -1099,33 +751,13 @@ public class SecurityStoreImplTest {
    @Test
    public void testCheckNoNotificationOnSuccess() throws Exception {
       NotificationService notificationService = 
Mockito.mock(NotificationService.class);
-      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), securityManager, 999, true, "", null, 
notificationService, 10, 10);
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, "", null, 
notificationService, 10, 10);
 
       final String user = "authorizedUser";
-      RemotingConnection connection = Mockito.mock(RemotingConnection.class);
-      securityStore.authenticate(user, "password", connection);
-
-      SecurityAuth session = new SecurityAuth() {
-         @Override
-         public String getUsername() {
-            return user;
-         }
-
-         @Override
-         public String getPassword() {
-            return "password";
-         }
-
-         @Override
-         public RemotingConnection getRemotingConnection() {
-            return connection;
-         }
+      final String password = "password";
+      securityStore.authenticate(user, password, 
Mockito.mock(RemotingConnection.class));
 
-         @Override
-         public String getSecurityDomain() {
-            return null;
-         }
-      };
+      SecurityAuth session = getSecurityAuth(user, password);
 
       // Successful check
       securityStore.check(SimpleString.of("test.address"), null, 
CheckType.SEND, session);
@@ -1133,4 +765,121 @@ public class SecurityStoreImplTest {
       // Verify NO notification was sent on success
       Mockito.verify(notificationService, 
Mockito.never()).sendNotification(ArgumentMatchers.any());
    }
+
+   @Test
+   public void testAuthenticateWithDefaultClusterCredentialsFails() throws 
Exception {
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, 
getDefaultClusterUser(), getDefaultClusterPassword(), null, 10, 10);
+
+      try {
+         securityStore.authenticate(getDefaultClusterUser(), 
getDefaultClusterPassword(), Mockito.mock(RemotingConnection.class), null);
+         fail("Should throw ActiveMQClusterSecurityException for default 
credentials");
+      } catch (ActiveMQSecurityException e) {
+         assertEquals(1, securityStore.getAuthenticationFailureCount());
+      }
+   }
+
+   @Test
+   public void testAuthenticateWithCorrectClusterCredentialsSucceeds() throws 
Exception {
+      final String clusterUser = "customClusterUser";
+      final String clusterPassword = "customClusterPassword";
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, clusterUser, 
clusterPassword, null, 10, 10);
+
+      String result = securityStore.authenticate(clusterUser, clusterPassword, 
Mockito.mock(RemotingConnection.class), null);
+      assertEquals(clusterUser, result);
+      assertEquals(1, securityStore.getAuthenticationSuccessCount());
+   }
+
+   @Test
+   public void testAuthenticateWithCorrectClusterUserButWrongPasswordFails() 
throws Exception {
+      final String clusterUser = "customClusterUser";
+      final String clusterPassword = "customClusterPassword";
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, clusterUser, 
clusterPassword, null, 10, 10);
+
+      try {
+         securityStore.authenticate(clusterUser, "wrongPassword", 
Mockito.mock(RemotingConnection.class), null);
+         fail("Should throw ActiveMQClusterSecurityException for wrong 
password");
+      } catch (ActiveMQSecurityException e) {
+         assertEquals(1, securityStore.getAuthenticationFailureCount());
+      }
+   }
+
+   @Test
+   public void testAuthenticateNonClusterUserFallsThrough() throws Exception {
+      final String clusterUser = "customClusterUser";
+      final String clusterPassword = "customClusterPassword";
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, clusterUser, 
clusterPassword, null, 10, 10);
+
+      String normalUser = "normalUser";
+      String normalPassword = "normalPassword";
+      String result = securityStore.authenticate(normalUser, normalPassword, 
Mockito.mock(RemotingConnection.class), null);
+      assertEquals(normalUser, result);
+      assertEquals(1, securityStore.getAuthenticationSuccessCount());
+   }
+
+   @Test
+   public void testClusterUserWithWrongPasswordDenied() throws Exception {
+      final String clusterUser = "customClusterUser";
+      final String clusterPassword = "customClusterPassword";
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, clusterUser, 
clusterPassword, null, 10, 10);
+
+      SecurityAuth session = getSecurityAuth(clusterUser, "wrongPassword");
+
+      // Wrong password should deny access
+      for (CheckType checkType : CheckType.values()) {
+         
assertFalse(securityStore.hasPermission(RandomUtil.randomUUIDSimpleString(), 
null, checkType, session));
+      }
+   }
+
+   @Test
+   public void testClusterUserWithDefaultCredentialsDenied() throws Exception {
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, 
getDefaultClusterUser(), getDefaultClusterPassword(), null, 10, 10);
+
+      SecurityAuth session = 
getSecurityAuth(ActiveMQDefaultConfiguration.getDefaultClusterUser(),
+                                             
ActiveMQDefaultConfiguration.getDefaultClusterPassword());
+
+      // Default credentials should be denied
+      for (CheckType checkType : CheckType.values()) {
+         
assertFalse(securityStore.hasPermission(RandomUtil.randomUUIDSimpleString(), 
null, checkType, session));
+      }
+   }
+
+   @Test
+   public void testCheckWithClusterUserAllowedPermission() throws Exception {
+      final String clusterUser = "customClusterUser";
+      final String clusterPassword = "customClusterPassword";
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, clusterUser, 
clusterPassword, null, 10, 10);
+
+      SecurityAuth session = getSecurityAuth(clusterUser, clusterPassword);
+
+      int checkCount = 0;
+      long initialSuccessCount = securityStore.getAuthorizationSuccessCount();
+      for (CheckType checkType : CheckType.values()) {
+         securityStore.check(RandomUtil.randomUUIDSimpleString(), null, 
checkType, session);
+         checkCount++;
+      }
+      assertEquals(initialSuccessCount + checkCount, 
securityStore.getAuthorizationSuccessCount());
+   }
+
+   @Test
+   public void testCheckWithDefaultClusterCredentialsThrowsException() throws 
Exception {
+      SecurityStoreImpl securityStore = new SecurityStoreImpl(new 
HierarchicalObjectRepository<>(), permitAll, 999, true, 
getDefaultClusterUser(), getDefaultClusterPassword(), null, 10, 10);
+
+      SecurityAuth session = 
getSecurityAuth(ActiveMQDefaultConfiguration.getDefaultClusterUser(),
+                                             
ActiveMQDefaultConfiguration.getDefaultClusterPassword());
+
+      try {
+         securityStore.check(RandomUtil.randomUUIDSimpleString(), null, 
CheckType.SEND, session);
+         fail("Should throw ActiveMQSecurityException for default cluster 
credentials");
+      } catch (ActiveMQSecurityException e) {
+         assertTrue(e.getMessage().contains(getDefaultClusterUser()));
+      }
+   }
+
+   private static SecurityAuth getSecurityAuth(String user, String password) {
+      SecurityAuth session = Mockito.mock(SecurityAuth.class);
+      Mockito.when(session.getUsername()).thenReturn(user);
+      Mockito.when(session.getPassword()).thenReturn(password);
+      
Mockito.when(session.getRemotingConnection()).thenReturn(Mockito.mock(RemotingConnection.class));
+      return session;
+   }
 }
diff --git a/docs/user-manual/_bridge-credentials-note.adoc 
b/docs/user-manual/_bridge-credentials-note.adoc
new file mode 100644
index 0000000000..7bb0079e84
--- /dev/null
+++ b/docs/user-manual/_bridge-credentials-note.adoc
@@ -0,0 +1,6 @@
+[NOTE]
+====
+Any target server with security enabled with reject the bridge's default 
`user` and `password` values.
+If security is enabled on the target broker (which is recommended) then set a 
`user` value that corresponds to a valid user account on the target broker.
+The corresponding role on the target broker should have the 
xref:security.adoc#role-based-security-for-addresses[`send` permission] for the 
bridge's `forwarding-address`.
+====
\ No newline at end of file
diff --git a/docs/user-manual/clusters.adoc b/docs/user-manual/clusters.adoc
index c200da4e91..cffb2e2a6c 100644
--- a/docs/user-manual/clusters.adoc
+++ b/docs/user-manual/clusters.adoc
@@ -594,7 +594,7 @@ Default is 30.
 
 === Cluster User Credentials
 
-When creating connections between nodes of a cluster to form a cluster 
connection, the broker uses a cluster user and cluster password which is 
defined in `broker.xml`:
+When creating connections between nodes of a cluster to form a cluster 
connection, the broker uses a cluster user and cluster password which is 
defined in `broker.xml` (shown with the default values):
 
 [,xml]
 ----
@@ -602,10 +602,12 @@ When creating connections between nodes of a cluster to 
form a cluster connectio
 <cluster-password>CHANGE ME!!</cluster-password>
 ----
 
-[WARNING]
+Every broker in the cluster must use matching values for `cluster-user` and 
`cluster-password`.
+
+[IMPORTANT]
 ====
-It is imperative that these values are changed from their default, or remote 
clients will be able to make connections to the server using the default values.
-If they are not changed from the default, the broker will detect this and 
pester you with a warning on every start-up.
+For safety, any connection using these credentials will be rejected.
+*In order for brokers to cluster together properly these values must be 
changed from their defaults.*
 ====
 
 == Client-Side Load balancing
diff --git a/docs/user-manual/core-bridges.adoc 
b/docs/user-manual/core-bridges.adoc
index 3ead650c0f..6db8169d45 100644
--- a/docs/user-manual/core-bridges.adoc
+++ b/docs/user-manual/core-bridges.adoc
@@ -174,12 +174,16 @@ Supports byte notation like "K", "MB", "MiB", "GB", etc.
 Default is `1048576` (i.e. 1MiB).
 
 user::
-This optional parameter determines the user name to use when creating the 
bridge connection to the remote server.
-If it is not specified the default cluster user specified by `cluster-user` in 
`broker.xml` will be used.
+This is the user name to use when creating the bridge connection to the remote 
server.
+If it is not specified the xref:clusters.adoc#cluster-user-credentials[default 
cluster user] will be used.
+
+include::_bridge-credentials-note.adoc[]
 
 password::
-This optional parameter determines the password to use when creating the 
bridge connection to the remote server.
-If it is not specified the default cluster password specified by 
`cluster-password` in `broker.xml` will be used.
+This is the password to use when creating the bridge connection to the remote 
server.
+If it is not specified the xref:clusters.adoc#cluster-user-credentials[default 
cluster password] will be used.
+
+include::_bridge-credentials-note.adoc[]
 
 reconnect-attempts-same-node::
 This configures the number of times reconnection attempts will be made to the 
same node on the topology before reverting back to the initial connector(s).
diff --git a/docs/user-manual/versions.adoc b/docs/user-manual/versions.adoc
index bec66a0e17..d1632d794d 100644
--- a/docs/user-manual/versions.adoc
+++ b/docs/user-manual/versions.adoc
@@ -15,6 +15,25 @@ NOTE: Follow the general upgrade procedure outlined in the 
xref:upgrading.adoc#u
 
 :sectnums!:
 
+== Version 2.54.0
+
+https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12315920&version=12356777[Full
 release notes]
+
+=== Highlights
+
+* xxx
+
+=== Upgrading from 2.53.0
+
+* To improve security we've hardened the code dealing with cluster credentials.
+In short, *any connection using the default values of `cluster-user` and 
`cluster-password` will be rejected*.
++
+Therefore, any broker using the default `cluster-user` and `cluster-password` 
will no longer cluster properly.
+To restore functionality, use a non-default value for `cluster-user` and 
`cluster-password`.
++
+This change similarly impacts any Core bridge connecting to a secured broker 
using the default `user` and `password` because those defaults are based on the 
default  `cluster-user` and `cluster-password` respectively.
+To restore functionality, we recommend specifying `user` and `password` values 
on the `bridge` that correspond to a valid user account on the target broker. 
The corresponding role on the target broker should have the 
xref:security.adoc#role-based-security-for-addresses[`send` permission] for the 
bridge's `forwarding-address`.
+
 == Version 2.53.0
 
 
https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12315920&version=12356748[Full
 release notes]
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/ClusterControllerDirectAuthTest.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/ClusterControllerDirectAuthTest.java
new file mode 100644
index 0000000000..3627f747bb
--- /dev/null
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/ClusterControllerDirectAuthTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.activemq.artemis.tests.integration.cluster;
+
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.apache.activemq.artemis.api.core.ActiveMQClusterSecurityException;
+import org.apache.activemq.artemis.api.core.client.ClientSession;
+import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
+import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import 
org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryInternal;
+import org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl;
+import org.apache.activemq.artemis.core.config.ClusterConnectionConfiguration;
+import org.apache.activemq.artemis.core.config.Configuration;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import 
org.apache.activemq.artemis.core.server.cluster.ActiveMQServerSideProtocolManagerFactory;
+import org.apache.activemq.artemis.core.server.cluster.ClusterControl;
+import org.apache.activemq.artemis.core.server.cluster.ClusterController;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.activemq.artemis.utils.ExecutorFactory;
+import org.apache.activemq.artemis.utils.RandomUtil;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import static 
org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration.getDefaultClusterPassword;
+import static 
org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration.getDefaultClusterUser;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.fail;
+
+public class ClusterControllerDirectAuthTest extends ActiveMQTestBase {
+
+   protected ActiveMQServer server;
+
+   protected ClientSession session;
+
+   protected ClientSessionFactory sf;
+
+   protected ServerLocator locator;
+
+   public void startServer(String clusterUser, String clusterPassword) throws 
Exception {
+      server = createServer(false, createDefaultInVMConfig()
+         .setSecurityEnabled(true)
+         .setClusterUser(clusterUser)
+         .setClusterPassword(clusterPassword)
+         .addConnectorConfiguration("fake-connector", "vm://1")
+         .addClusterConfiguration(new ClusterConnectionConfiguration()
+                                     .setName("fake-cluster-connection")
+                                     .setConnectorName("fake-connector")));
+      server.start();
+   }
+
+   @Test
+   public void testDirectClusterAuthWithDefaultCredentials() throws Exception {
+      testDirectClusterAuth(getDefaultClusterUser(), 
getDefaultClusterPassword(), false);
+   }
+
+   @Test
+   public void testDirectClusterAuthWithCustomCredentials() throws Exception {
+      testDirectClusterAuth(RandomUtil.randomUUIDString(), 
RandomUtil.randomUUIDString(), true);
+   }
+
+   private void testDirectClusterAuth(String clusterUser, String 
clusterPassword, boolean shouldSucceed) throws Exception {
+      startServer(clusterUser, clusterPassword);
+      try (ServerLocatorImpl locator = (ServerLocatorImpl) 
createInVMNonHALocator()) {
+         
locator.setProtocolManagerFactory(ActiveMQServerSideProtocolManagerFactory.getInstance(locator,
 server.getStorageManager()));
+         ClusterController controller = getClusterController(clusterUser, 
clusterPassword);
+         ClusterControl clusterControl = 
controller.connectToNodeInCluster((ClientSessionFactoryInternal) 
locator.createSessionFactory());
+         if (shouldSucceed) {
+            clusterControl.authorize();
+         } else {
+            try {
+               clusterControl.authorize();
+               fail("should throw ActiveMQClusterSecurityException");
+            } catch (Exception e) {
+               assertInstanceOf(ActiveMQClusterSecurityException.class, e, 
"should throw ActiveMQClusterSecurityException");
+            }
+         }
+      }
+   }
+
+   private ClusterController getClusterController(String clusterUser, String 
clusterPassword) {
+      Configuration mockConfig = Mockito.mock(Configuration.class);
+      Mockito.when(mockConfig.getClusterUser()).thenReturn(clusterUser);
+      
Mockito.when(mockConfig.getClusterPassword()).thenReturn(clusterPassword);
+
+      ActiveMQServer mockServer = Mockito.mock(ActiveMQServer.class);
+      
Mockito.when(mockServer.getExecutorFactory()).thenReturn(Mockito.mock(ExecutorFactory.class));
+      Mockito.when(mockServer.getConfiguration()).thenReturn(mockConfig);
+
+      return new ClusterController(mockServer, 
Mockito.mock(ScheduledExecutorService.class), false);
+   }
+}
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/topology/TopologyClusterTestBase.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/topology/TopologyClusterTestBase.java
index 769f7ae24a..7f5cbff879 100644
--- 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/topology/TopologyClusterTestBase.java
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/topology/TopologyClusterTestBase.java
@@ -26,6 +26,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 
 import org.apache.activemq.artemis.api.core.ActiveMQException;
@@ -41,9 +42,11 @@ import 
org.apache.activemq.artemis.api.core.client.ClusterTopologyListener;
 import org.apache.activemq.artemis.api.core.client.ServerLocator;
 import org.apache.activemq.artemis.api.core.client.TopologyMember;
 import org.apache.activemq.artemis.core.config.Configuration;
+import org.apache.activemq.artemis.core.security.Role;
 import org.apache.activemq.artemis.core.server.ActiveMQServer;
 import org.apache.activemq.artemis.core.server.cluster.ClusterConnection;
 import org.apache.activemq.artemis.core.server.cluster.ClusterManager;
+import 
org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
 import 
org.apache.activemq.artemis.tests.integration.cluster.distribution.ClusterTestBase;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.apache.activemq.artemis.tests.util.Wait;
@@ -348,27 +351,33 @@ public abstract class TopologyClusterTestBase extends 
ClusterTestBase {
 
    @Test
    public void testWrongPasswordTriggersClusterConnectionStop() throws 
Exception {
-      Configuration config = servers[4].getConfiguration();
+      final String user = "myUser";
+      final String password = "myPassword";
+      final String role = "myRole";
+
       for (ActiveMQServer s : servers) {
          if (s != null) {
             s.getConfiguration().setSecurityEnabled(true);
          }
       }
+      Configuration config = servers[4].getConfiguration();
       assertEquals(ActiveMQTestBase.CLUSTER_PASSWORD, 
config.getClusterPassword());
       config.setClusterPassword(config.getClusterPassword() + "-1-2-3-");
+      final String address = "foo1235";
+      
((ActiveMQJAASSecurityManager)servers[0].getSecurityManager()).getConfiguration().addUser(user,
 password);
+      
((ActiveMQJAASSecurityManager)servers[0].getSecurityManager()).getConfiguration().addRole(user,
 role);
+      servers[0].getSecurityRepository().addMatch(address, Set.of(new 
Role(role, true, true, true, false, false, false, false, false, true, false, 
false, false)));
       startServers(0, 4);
       assertTrue(Wait.waitFor(() -> 
!servers[4].getClusterManager().isStarted() || 
!servers[0].getClusterManager().isStarted(), 5000), "one or the other cluster 
managers should stop");
-      final String address = "foo1235";
       ServerLocator locator = createNonHALocator(isNetty());
       ClientSessionFactory sf = createSessionFactory(locator);
-      ClientSession session = sf.createSession(config.getClusterUser(), 
ActiveMQTestBase.CLUSTER_PASSWORD, false, true, true, false, 1);
+      ClientSession session = sf.createSession(user, password, false, true, 
true, false, 1);
       session.createQueue(QueueConfiguration.of(address));
       ClientProducer producer = session.createProducer(address);
       sendMessages(session, producer, 100);
       ClientConsumer consumer = session.createConsumer(address);
       session.start();
       receiveMessages(consumer, 0, 100, true);
-
    }
 
    @Test
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SecurityManagementWithConfiguredAdminUserTest.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SecurityManagementWithConfiguredAdminUserTest.java
index f378c4a6d9..715755f244 100644
--- 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SecurityManagementWithConfiguredAdminUserTest.java
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SecurityManagementWithConfiguredAdminUserTest.java
@@ -42,7 +42,7 @@ public class SecurityManagementWithConfiguredAdminUserTest 
extends SecurityManag
     * default CLUSTER_ADMIN_USER must work even when there are other 
configured admin users
     */
    @TestTemplate
-   public void testSendManagementMessageWithClusterAdminUser() throws 
Exception {
+   public void testSendManagementMessageWithNonDefaultClusterAdminUser() 
throws Exception {
       
doSendBrokerManagementMessage(ActiveMQDefaultConfiguration.getDefaultClusterUser(),
 CLUSTER_PASSWORD, true);
    }
 
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SecurityManagementWithDefaultConfigurationTest.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SecurityManagementWithDefaultConfigurationTest.java
index 4c0b0a58c3..d3c1c59d02 100644
--- 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SecurityManagementWithDefaultConfigurationTest.java
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/SecurityManagementWithDefaultConfigurationTest.java
@@ -31,7 +31,7 @@ public class SecurityManagementWithDefaultConfigurationTest 
extends SecurityMana
 
    @TestTemplate
    public void testSendManagementMessageWithDefaultClusterAdminUser() throws 
Exception {
-      
doSendBrokerManagementMessage(ActiveMQDefaultConfiguration.getDefaultClusterUser(),
 ActiveMQDefaultConfiguration.getDefaultClusterPassword(), true);
+      
doSendBrokerManagementMessage(ActiveMQDefaultConfiguration.getDefaultClusterUser(),
 ActiveMQDefaultConfiguration.getDefaultClusterPassword(), false);
    }
 
    @TestTemplate
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/ScaleDown3NodeTest.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/ScaleDown3NodeTest.java
index 2486e76003..18c40d1822 100644
--- 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/ScaleDown3NodeTest.java
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/ScaleDown3NodeTest.java
@@ -30,12 +30,16 @@ import 
org.apache.activemq.artemis.api.core.client.ClientProducer;
 import org.apache.activemq.artemis.api.core.client.ClientSession;
 import org.apache.activemq.artemis.core.config.ScaleDownConfiguration;
 import 
org.apache.activemq.artemis.core.config.ha.PrimaryOnlyPolicyConfiguration;
+import org.apache.activemq.artemis.core.config.impl.SecurityConfiguration;
 import 
org.apache.activemq.artemis.core.persistence.impl.journal.LargeServerMessageImpl;
 import org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding;
 import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.core.security.Role;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
 import org.apache.activemq.artemis.core.server.Queue;
 import 
org.apache.activemq.artemis.core.server.cluster.impl.MessageLoadBalancingType;
 import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
+import 
org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
 import 
org.apache.activemq.artemis.tests.integration.cluster.distribution.ClusterTestBase;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.apache.activemq.artemis.tests.util.Wait;
@@ -44,21 +48,27 @@ import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import java.lang.invoke.MethodHandles;
+import java.util.Set;
 
 public class ScaleDown3NodeTest extends ClusterTestBase {
 
    private static final Logger logger = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
+   private final String userName = "myUser";
+   private final String password = "myPassword";
+   private final String role = "myRole";
+
    @Override
    @BeforeEach
    public void setUp() throws Exception {
       super.setUp();
       setupPrimaryServer(0, isFileStorage(), HAType.SharedNothingReplication, 
isNetty(), true);
       servers[0].getConfiguration().setSecurityEnabled(true);
+      configureSecurity(servers[0]);
       setupPrimaryServer(1, isFileStorage(), HAType.SharedNothingReplication, 
isNetty(), true);
-      servers[1].getConfiguration().setSecurityEnabled(true);
+      configureSecurity(servers[1]);
       setupPrimaryServer(2, isFileStorage(), HAType.SharedNothingReplication, 
isNetty(), true);
-      servers[2].getConfiguration().setSecurityEnabled(true);
+      configureSecurity(servers[2]);
       PrimaryOnlyPolicyConfiguration haPolicyConfiguration0 = 
(PrimaryOnlyPolicyConfiguration) 
servers[0].getConfiguration().getHAPolicyConfiguration();
       ScaleDownConfiguration scaleDownConfiguration0 = new 
ScaleDownConfiguration();
       
haPolicyConfiguration0.setScaleDownConfiguration(scaleDownConfiguration0);
@@ -90,6 +100,13 @@ public class ScaleDown3NodeTest extends ClusterTestBase {
       servers[2].setIdentity("Node2");
    }
 
+   private void configureSecurity(ActiveMQServer server) {
+      SecurityConfiguration securityConfiguration = 
((ActiveMQJAASSecurityManager)server.getSecurityManager()).getConfiguration();
+      securityConfiguration.addUser(userName, password);
+      securityConfiguration.addRole(userName, role);
+      server.getSecurityRepository().addMatch("testAddress.#", Set.of(new 
Role(role, false, true, false, false, true, false, false, false, true, false, 
false, false)));
+   }
+
    protected boolean isNetty() {
       return true;
    }
@@ -124,16 +141,16 @@ public class ScaleDown3NodeTest extends ClusterTestBase {
       final String queueName1 = "testQueue1";
 
       // create a queue on each node mapped to the same address
-      createQueue(0, addressName, queueName1, null, false, 
servers[0].getConfiguration().getClusterUser(), 
servers[0].getConfiguration().getClusterPassword());
-      createQueue(1, addressName, queueName1, null, false, 
servers[1].getConfiguration().getClusterUser(), 
servers[1].getConfiguration().getClusterPassword());
-      createQueue(2, addressName, queueName1, null, false, 
servers[2].getConfiguration().getClusterUser(), 
servers[2].getConfiguration().getClusterPassword());
+      createQueue(0, addressName, queueName1, null, false, userName, password);
+      createQueue(1, addressName, queueName1, null, false, userName, password);
+      createQueue(2, addressName, queueName1, null, false, userName, password);
 
       // pause the SnF queue so that when the server tries to redistribute a 
message it won't actually go across the cluster bridge
       final String snfAddress = servers[0].getInternalNamingPrefix() + 
"sf.cluster0." + servers[0].getNodeID().toString();
       Queue snfQueue = ((LocalQueueBinding) 
servers[2].getPostOffice().getBinding(SimpleString.of(snfAddress))).getQueue();
       snfQueue.pause();
 
-      ClientSession session = 
sfs[2].createSession(servers[2].getConfiguration().getClusterUser(), 
servers[2].getConfiguration().getClusterPassword(), false, true, false, false, 
0);
+      ClientSession session = sfs[2].createSession(userName, password, false, 
true, false, false, 0);
 
       Message message;
 
@@ -166,7 +183,7 @@ public class ScaleDown3NodeTest extends ClusterTestBase {
       }
 
       // add a consumer to node 0 to trigger redistribution here
-      addConsumer(0, 0, queueName1, null, true, 
servers[0].getConfiguration().getClusterUser(), 
servers[0].getConfiguration().getClusterPassword());
+      addConsumer(0, 0, queueName1, null, true, userName, password);
 
       Wait.assertEquals(TEST_SIZE, snfQueue::getMessageCount);
 
@@ -183,7 +200,7 @@ public class ScaleDown3NodeTest extends ClusterTestBase {
       Wait.assertEquals(0, queueServer2::getMessageCount);
 
       // get the messages from queue 1 on node 1
-      addConsumer(0, 1, queueName1, null, true, 
servers[1].getConfiguration().getClusterUser(), 
servers[1].getConfiguration().getClusterPassword());
+      addConsumer(0, 1, queueName1, null, true, userName, password);
 
       // ensure the message is in queue 1 on node 1 as expected
       Queue queueServer1 = ((LocalQueueBinding) 
servers[1].getPostOffice().getBinding(SimpleString.of(queueName1))).getQueue();
@@ -229,26 +246,26 @@ public class ScaleDown3NodeTest extends ClusterTestBase {
       final String queueName3 = "testQueue3";
 
       // create a queue on each node mapped to the same address
-      createQueue(0, addressName, queueName1, null, false, 
servers[0].getConfiguration().getClusterUser(), 
servers[0].getConfiguration().getClusterPassword());
-      createQueue(1, addressName, queueName1, null, false, 
servers[1].getConfiguration().getClusterUser(), 
servers[1].getConfiguration().getClusterPassword());
-      createQueue(2, addressName, queueName1, null, false, 
servers[2].getConfiguration().getClusterUser(), 
servers[2].getConfiguration().getClusterPassword());
+      createQueue(0, addressName, queueName1, null, false, userName, password);
+      createQueue(1, addressName, queueName1, null, false, userName, password);
+      createQueue(2, addressName, queueName1, null, false, userName, password);
 
       // create a queue on each node mapped to the same address
-      createQueue(0, addressName, queueName2, null, false, 
servers[0].getConfiguration().getClusterUser(), 
servers[0].getConfiguration().getClusterPassword());
-      createQueue(1, addressName, queueName2, null, false, 
servers[1].getConfiguration().getClusterUser(), 
servers[1].getConfiguration().getClusterPassword());
-      createQueue(2, addressName, queueName2, null, false, 
servers[2].getConfiguration().getClusterUser(), 
servers[2].getConfiguration().getClusterPassword());
+      createQueue(0, addressName, queueName2, null, false, userName, password);
+      createQueue(1, addressName, queueName2, null, false, userName, password);
+      createQueue(2, addressName, queueName2, null, false, userName, password);
 
       // create a queue on each node mapped to the same address
-      createQueue(0, addressName, queueName3, null, false, 
servers[0].getConfiguration().getClusterUser(), 
servers[0].getConfiguration().getClusterPassword());
-      createQueue(1, addressName, queueName3, null, false, 
servers[1].getConfiguration().getClusterUser(), 
servers[1].getConfiguration().getClusterPassword());
-      createQueue(2, addressName, queueName3, null, false, 
servers[2].getConfiguration().getClusterUser(), 
servers[2].getConfiguration().getClusterPassword());
+      createQueue(0, addressName, queueName3, null, false, userName, password);
+      createQueue(1, addressName, queueName3, null, false, userName, password);
+      createQueue(2, addressName, queueName3, null, false, userName, password);
 
       // pause the SnF queue so that when the server tries to redistribute a 
message it won't actually go across the cluster bridge
       String snfAddress = servers[0].getInternalNamingPrefix() + 
"sf.cluster0." + servers[0].getNodeID().toString();
       Queue snfQueue = ((LocalQueueBinding) 
servers[2].getPostOffice().getBinding(SimpleString.of(snfAddress))).getQueue();
       snfQueue.pause();
 
-      ClientSession session = 
sfs[2].createSession(servers[2].getConfiguration().getClusterUser(), 
servers[2].getConfiguration().getClusterPassword(), false, true, false, false, 
0);
+      ClientSession session = sfs[2].createSession(userName, password, false, 
true, false, false, 0);
 
       Message message;
       message = session.createMessage(false);
@@ -259,8 +276,8 @@ public class ScaleDown3NodeTest extends ClusterTestBase {
       }
 
       // add a consumer to node 0 to trigger redistribution here
-      addConsumer(0, 0, queueName1, null, true, 
servers[0].getConfiguration().getClusterUser(), 
servers[0].getConfiguration().getClusterPassword());
-      addConsumer(1, 0, queueName3, null, true, 
servers[0].getConfiguration().getClusterUser(), 
servers[0].getConfiguration().getClusterPassword());
+      addConsumer(0, 0, queueName1, null, true, userName, password);
+      addConsumer(1, 0, queueName3, null, true, userName, password);
 
       // ensure the message is in the SnF queue
       Wait.assertEquals(TEST_SIZE * 2, snfQueue::getMessageCount);
@@ -277,8 +294,8 @@ public class ScaleDown3NodeTest extends ClusterTestBase {
       assertEquals(TEST_SIZE, getMessageCount(((LocalQueueBinding) 
servers[2].getPostOffice().getBinding(SimpleString.of(queueName2))).getQueue()));
 
       // get the messages from queue 1 on node 1
-      addConsumer(0, 1, queueName1, null, true, 
servers[1].getConfiguration().getClusterUser(), 
servers[1].getConfiguration().getClusterPassword());
-      addConsumer(1, 1, queueName3, null, true, 
servers[1].getConfiguration().getClusterUser(), 
servers[1].getConfiguration().getClusterPassword());
+      addConsumer(0, 1, queueName1, null, true, userName, password);
+      addConsumer(1, 1, queueName3, null, true, userName, password);
 
       Wait.assertEquals(TEST_SIZE * 2, () -> 
getMessageCount(((LocalQueueBinding) 
servers[1].getPostOffice().getBinding(SimpleString.of(queueName1))).getQueue()) 
+
          getMessageCount(((LocalQueueBinding) 
servers[1].getPostOffice().getBinding(SimpleString.of(queueName3))).getQueue()));
diff --git 
a/tests/smoke-tests/src/main/resources/servers/bridgeTransfer/serverA/broker.xml
 
b/tests/smoke-tests/src/main/resources/servers/bridgeTransfer/serverA/broker.xml
index 914030f308..f9060c6404 100644
--- 
a/tests/smoke-tests/src/main/resources/servers/bridgeTransfer/serverA/broker.xml
+++ 
b/tests/smoke-tests/src/main/resources/servers/bridgeTransfer/serverA/broker.xml
@@ -152,6 +152,8 @@ under the License.
             <queue-name>bridgeQueue</queue-name>
             <retry-interval>100</retry-interval>
             <reconnect-attempts>-1</reconnect-attempts>
+            <user>artemis</user>
+            <password>artemis</password>
             <static-connectors>
                <connector-ref>other-side</connector-ref>
             </static-connectors>
diff --git 
a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/clusteredLargeMessage/ClusteredLargeMessageTest.java
 
b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/clusteredLargeMessage/ClusteredLargeMessageTest.java
index 221dfa9df9..388bce2101 100644
--- 
a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/clusteredLargeMessage/ClusteredLargeMessageTest.java
+++ 
b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/clusteredLargeMessage/ClusteredLargeMessageTest.java
@@ -55,14 +55,14 @@ public class ClusteredLargeMessageTest extends 
SmokeTestBase {
          HelperCreate cliCreateServer = helperCreate();
          
cliCreateServer.setRole("amq").setUser("artemis").setPassword("artemis").setAllowAnonymous(true).setNoWeb(true).
             setArtemisInstance(server0Location).setClustered(true).
-               setStaticCluster("tcp://localhost:61716").setArgs("--name", 
"cluster1", "--max-hops", "1", "--queues", "testQueue");
+               setStaticCluster("tcp://localhost:61716").setArgs("--name", 
"cluster1", "--max-hops", "1", "--queues", "testQueue", "--cluster-user", 
"artemis", "--cluster-password", "artemis");
          cliCreateServer.createServer();
       }
       {
          HelperCreate cliCreateServer = helperCreate();
          
cliCreateServer.setRole("amq").setUser("artemis").setPassword("artemis").setAllowAnonymous(true).setNoWeb(true).setPortOffset(100).
             setArtemisInstance(server1Location).setClustered(true).
-               setStaticCluster("tcp://localhost:61616").setArgs("--name", 
"cluster2", "--max-hops", "1", "--queues", "testQueue");
+               setStaticCluster("tcp://localhost:61616").setArgs("--name", 
"cluster2", "--max-hops", "1", "--queues", "testQueue", "--cluster-user", 
"artemis", "--cluster-password", "artemis");
          cliCreateServer.createServer();
       }
    }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to