You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cl...@apache.org on 2016/01/19 15:46:01 UTC

[3/3] activemq-artemis git commit: ARTEMIS-349 LDAP plugin listener

ARTEMIS-349 LDAP plugin listener

This feature required a bit of refactoring to the plugin interface itself as
well as a restriction on the configuration so that either only one plugin could
be specified or an ulimited number of security-setting matches. This was done
to prevent messy situations where a plugin could update settings from the XML
or even another plugin if there were overlapping matches.


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/d94c044e
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/d94c044e
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/d94c044e

Branch: refs/heads/master
Commit: d94c044e900407134ca426827ccd7b73594aca6f
Parents: 3433f53
Author: jbertram <jb...@apache.org>
Authored: Mon Jan 11 16:39:35 2016 -0600
Committer: Clebert Suconic <cl...@apache.org>
Committed: Tue Jan 19 09:45:52 2016 -0500

----------------------------------------------------------------------
 .../artemis/core/config/Configuration.java      |   2 +
 .../core/config/impl/ConfigurationImpl.java     |   6 +
 .../deployers/impl/FileConfigurationParser.java |   4 +-
 .../core/server/SecuritySettingPlugin.java      |  24 +-
 .../core/server/impl/ActiveMQServerImpl.java    |   9 +
 .../impl/LegacyLDAPSecuritySettingPlugin.java   | 375 +++++++++++++++----
 .../resources/schema/artemis-configuration.xsd  |   6 +-
 .../impl/FileConfigurationParserTest.java       |  12 +-
 .../core/config/impl/FileConfigurationTest.java |  25 +-
 .../resources/ConfigurationTest-full-config.xml |  14 -
 .../resources/InvalidConfigurationTest6.xml     |  45 +++
 .../test/resources/securitySettingPlugin.xml    |  40 ++
 docs/user-manual/en/security.md                 |  47 +--
 .../integration/openwire/OpenWireTestBase.java  |  23 +-
 .../integration/security/LDAPSecurityTest.java  |   4 +-
 ...cyLDAPSecuritySettingPluginListenerTest.java | 352 +++++++++++++++++
 .../LegacyLDAPSecuritySettingPluginTest.java    |   3 +-
 .../integration/security/SecurityTest.java      |  10 +-
 18 files changed, 817 insertions(+), 184 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java
index 96d5050..e493769 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java
@@ -868,6 +868,8 @@ public interface Configuration {
     */
    Map<String, Set<Role>> getSecurityRoles();
 
+   Configuration putSecurityRoles(String match, Set<Role> roles);
+
    Configuration setConnectorServiceConfigurations(List<ConnectorServiceConfiguration> configs);
 
    Configuration addConnectorServiceConfiguration(ConnectorServiceConfiguration config);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java
index fc36809..0a6582f 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java
@@ -1145,6 +1145,12 @@ public class ConfigurationImpl implements Configuration, Serializable {
    }
 
    @Override
+   public ConfigurationImpl putSecurityRoles(String match, Set<Role> roles) {
+      securitySettings.put(match, roles);
+      return this;
+   }
+
+   @Override
    public ConfigurationImpl setSecurityRoles(final Map<String, Set<Role>> securitySettings) {
       this.securitySettings = securitySettings;
       return this;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
index 8b11b3b..e34207e 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
@@ -541,12 +541,12 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
          NodeList list = node.getElementsByTagName(SECURITY_ELEMENT_NAME);
          for (int i = 0; i < list.getLength(); i++) {
             Pair<String, Set<Role>> securityItem = parseSecurityRoles(list.item(i));
-            config.getSecurityRoles().put(securityItem.getA(), securityItem.getB());
+            config.putSecurityRoles(securityItem.getA(), securityItem.getB());
          }
          list = node.getElementsByTagName(SECURITY_PLUGIN_ELEMENT_NAME);
          for (int i = 0; i < list.getLength(); i++) {
             Pair<SecuritySettingPlugin, Map<String, String>> securityItem = parseSecuritySettingPlugins(list.item(i));
-            config.addSecuritySettingPlugin(securityItem.getA().init(securityItem.getB()).populateSecurityRoles());
+            config.addSecuritySettingPlugin(securityItem.getA().init(securityItem.getB()));
          }
       }
    }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/SecuritySettingPlugin.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/SecuritySettingPlugin.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/SecuritySettingPlugin.java
index 0803e2f..7b22b61 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/SecuritySettingPlugin.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/SecuritySettingPlugin.java
@@ -21,6 +21,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.activemq.artemis.core.security.Role;
+import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
 
 public interface SecuritySettingPlugin extends Serializable {
    /**
@@ -35,8 +36,14 @@ public interface SecuritySettingPlugin extends Serializable {
    SecuritySettingPlugin init(Map<String, String> options);
 
    /**
-    * Once {@code #populateSecurityRoles} is invoked this method should return the security role information from the
-    * external environment (e.g. file, LDAP, etc.).
+    * Clean up all the associated resources associated with this plugin (e.g. LDAP connections, file handles, etc.)
+    *
+    * @return {@code this} instance
+    */
+   SecuritySettingPlugin stop();
+
+   /**
+    * Fetch the security role information from the external environment (e.g. file, LDAP, etc.) and return it.
     *
     * @return the Map's key corresponds to the "match" for the security setting and the corresponding value is the set of
     * {@code org.apache.activemq.artemis.core.security.Role} objects defining the appropriate authorization
@@ -44,14 +51,11 @@ public interface SecuritySettingPlugin extends Serializable {
    Map<String, Set<Role>> getSecurityRoles();
 
    /**
-    * Fetch the security role information from the external environment (e.g. file, LDAP, etc.). This method should put
-    * the security role information in the variable that is returned by {@code #getSecurityRoles()}. This method is
-    * called by the broker when the file-based configuration is read (see {@code org.apache.activemq.artemis.core.deployers.impl.FileConfigurationParser#parseSecurity(org.w3c.dom.Element, org.apache.activemq.artemis.core.config.Configuration)}
-    * so that later when {@code #getSecurityRoles()} is called by {@code org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl#deploySecurity()}
-    * the necessary information will be present. If you're creating/configuring the plugin programmatically then you'll
-    * want to invoke this method soon after instantiating and configuring it.
+    * This method is called by the broker during the start-up process. It's for plugins that might need to modify the
+    * security settings during runtime (e.g. LDAP plugin that uses a listener to receive updates, etc.). Any changes
+    * made to this {@code HierarchicalRepository} will be reflected in the broker.
     *
-    * @return {@code this} instance
+    * @param securityRepository
     */
-   SecuritySettingPlugin populateSecurityRoles();
+   void setSecurityRepository(HierarchicalRepository<Set<Role>> securityRepository);
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
----------------------------------------------------------------------
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 58993fc..abdf428 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
@@ -104,6 +104,7 @@ import org.apache.activemq.artemis.core.server.NodeManager;
 import org.apache.activemq.artemis.core.server.Queue;
 import org.apache.activemq.artemis.core.server.QueueCreator;
 import org.apache.activemq.artemis.core.server.QueueFactory;
+import org.apache.activemq.artemis.core.server.SecuritySettingPlugin;
 import org.apache.activemq.artemis.core.server.ServerSession;
 import org.apache.activemq.artemis.core.server.ServerSessionFactory;
 import org.apache.activemq.artemis.core.server.ServiceRegistry;
@@ -696,6 +697,10 @@ public class ActiveMQServerImpl implements ActiveMQServer {
 
       stopComponent(memoryManager);
 
+      for (SecuritySettingPlugin securitySettingPlugin : configuration.getSecuritySettingPlugins()) {
+         securitySettingPlugin.stop();
+      }
+
       if (threadPool != null && !threadPoolSupplied) {
          threadPool.shutdown();
          try {
@@ -1739,6 +1744,10 @@ public class ActiveMQServerImpl implements ActiveMQServer {
       for (Map.Entry<String, Set<Role>> entry : configuration.getSecurityRoles().entrySet()) {
          securityRepository.addMatch(entry.getKey(), entry.getValue(), true);
       }
+
+      for (SecuritySettingPlugin securitySettingPlugin : configuration.getSecuritySettingPlugins()) {
+         securitySettingPlugin.setSecurityRepository(securityRepository);
+      }
    }
 
    private void deployQueuesFromConfiguration() throws Exception {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/LegacyLDAPSecuritySettingPlugin.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/LegacyLDAPSecuritySettingPlugin.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/LegacyLDAPSecuritySettingPlugin.java
index 21de3d7..936ae9a 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/LegacyLDAPSecuritySettingPlugin.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/LegacyLDAPSecuritySettingPlugin.java
@@ -25,17 +25,25 @@ import javax.naming.directory.DirContext;
 import javax.naming.directory.InitialDirContext;
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
+import javax.naming.event.EventDirContext;
+import javax.naming.event.NamespaceChangeListener;
+import javax.naming.event.NamingEvent;
+import javax.naming.event.NamingExceptionEvent;
+import javax.naming.event.ObjectChangeListener;
 import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import org.apache.activemq.artemis.core.security.Role;
-import org.apache.activemq.artemis.core.server.SecuritySettingPlugin;
 import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
+import org.apache.activemq.artemis.core.server.SecuritySettingPlugin;
+import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
 
 public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
    private static final long serialVersionUID = 4793109879399750045L;
@@ -52,6 +60,7 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
    public static final String ADMIN_PERMISSION_VALUE = "adminPermissionValue";
    public static final String READ_PERMISSION_VALUE = "readPermissionValue";
    public static final String WRITE_PERMISSION_VALUE = "writePermissionValue";
+   public static final String ENABLE_LISTENER = "enableListener";
 
    private String initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
    private String connectionURL = "ldap://localhost:1024";
@@ -65,30 +74,43 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
    private String adminPermissionValue = "admin";
    private String readPermissionValue = "read";
    private String writePermissionValue = "write";
+   private boolean enableListener = true;
 
    private DirContext context;
-   private Map<String, Set<Role>> securityRoles = new HashMap<>();
+   private EventDirContext eventContext;
+   private Map<String, Set<Role>> securityRoles;
+   private HierarchicalRepository<Set<Role>> securityRepository;
 
    @Override
    public LegacyLDAPSecuritySettingPlugin init(Map<String, String> options) {
       if (options != null) {
-         initialContextFactory = options.get(INITIAL_CONTEXT_FACTORY);
-         connectionURL = options.get(CONNECTION_URL);
-         connectionUsername = options.get(CONNECTION_USERNAME);
-         connectionPassword = options.get(CONNECTION_PASSWORD);
-         connectionProtocol = options.get(CONNECTION_PROTOCOL);
-         authentication = options.get(AUTHENTICATION);
-         destinationBase = options.get(DESTINATION_BASE);
-         filter = options.get(FILTER);
-         roleAttribute = options.get(ROLE_ATTRIBUTE);
-         adminPermissionValue = options.get(ADMIN_PERMISSION_VALUE);
-         readPermissionValue = options.get(READ_PERMISSION_VALUE);
-         writePermissionValue = options.get(WRITE_PERMISSION_VALUE);
+         initialContextFactory = getOption(options, INITIAL_CONTEXT_FACTORY, initialContextFactory);
+         connectionURL = getOption(options, CONNECTION_URL, connectionURL);
+         connectionUsername = getOption(options, CONNECTION_USERNAME, connectionUsername);
+         connectionPassword = getOption(options, CONNECTION_PASSWORD, connectionPassword);
+         connectionProtocol = getOption(options, CONNECTION_PROTOCOL, connectionProtocol);
+         authentication = getOption(options, AUTHENTICATION, authentication);
+         destinationBase = getOption(options, DESTINATION_BASE, destinationBase);
+         filter = getOption(options, FILTER, filter);
+         roleAttribute = getOption(options, ROLE_ATTRIBUTE, roleAttribute);
+         adminPermissionValue = getOption(options, ADMIN_PERMISSION_VALUE, adminPermissionValue);
+         readPermissionValue = getOption(options, READ_PERMISSION_VALUE, readPermissionValue);
+         writePermissionValue = getOption(options, WRITE_PERMISSION_VALUE, writePermissionValue);
+         enableListener = getOption(options, ENABLE_LISTENER, Boolean.TRUE.toString()).equalsIgnoreCase(Boolean.TRUE.toString());
       }
 
       return this;
    }
 
+   private String getOption(Map<String, String> options, String key, String defaultValue) {
+      String result = options.get(key);
+      if (result == null) {
+         result = defaultValue;
+      }
+
+      return result;
+   }
+
    public String getRoleAttribute() {
       return roleAttribute;
    }
@@ -197,11 +219,46 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
       return this;
    }
 
-   protected void open() throws NamingException {
+   public boolean isEnableListener() {
+      return enableListener;
+   }
+
+   public LegacyLDAPSecuritySettingPlugin setEnableListener(boolean enableListener) {
+      this.enableListener = enableListener;
+      return this;
+   }
+
+   protected boolean isContextAlive() {
+      boolean alive = false;
       if (context != null) {
+         try {
+            context.getAttributes("");
+            alive = true;
+         }
+         catch (Exception e) {
+         }
+      }
+      return alive;
+   }
+
+   protected void open() throws NamingException {
+      if (isContextAlive()) {
          return;
       }
 
+      context = createContext();
+      eventContext = ((EventDirContext) context.lookup(""));
+
+      SearchControls searchControls = new SearchControls();
+      searchControls.setReturningAttributes(new String[]{roleAttribute});
+      searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+
+      if (enableListener) {
+         eventContext.addNamingListener(destinationBase, filter, searchControls, new LDAPNamespaceChangeListener());
+      }
+   }
+
+   private DirContext createContext() throws NamingException {
       Hashtable<String, String> env = new Hashtable<>();
       env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
       if (connectionUsername != null && !"".equals(connectionUsername)) {
@@ -219,16 +276,18 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
       env.put(Context.SECURITY_PROTOCOL, connectionProtocol);
       env.put(Context.PROVIDER_URL, connectionURL);
       env.put(Context.SECURITY_AUTHENTICATION, authentication);
-      context = new InitialDirContext(env);
+      return new InitialDirContext(env);
    }
 
    @Override
    public Map<String, Set<Role>> getSecurityRoles() {
+      if (securityRoles == null) {
+         populateSecurityRoles();
+      }
       return securityRoles;
    }
 
-   @Override
-   public LegacyLDAPSecuritySettingPlugin populateSecurityRoles() {
+   private LegacyLDAPSecuritySettingPlugin populateSecurityRoles() {
       ActiveMQServerLogger.LOGGER.populatingSecurityRolesFromLDAP(connectionURL);
       try {
          open();
@@ -242,80 +301,240 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
       searchControls.setReturningAttributes(new String[]{roleAttribute});
       searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
 
-      Map<String, Set<Role>> securityRoles = new HashMap<>();
+      securityRoles = new HashMap<>();
       try {
          NamingEnumeration<SearchResult> searchResults = context.search(destinationBase, filter, searchControls);
-         int i = 0;
          while (searchResults.hasMore()) {
-            SearchResult searchResult = searchResults.next();
-            Attributes attrs = searchResult.getAttributes();
-            if (attrs == null || attrs.size() == 0) {
-               continue;
+            processSearchResult(securityRoles, searchResults.next());
+         }
+      }
+      catch (Exception e) {
+         ActiveMQServerLogger.LOGGER.errorPopulatingSecurityRolesFromLDAP(e);
+      }
+
+      return this;
+   }
+
+   @Override
+   public void setSecurityRepository(HierarchicalRepository<Set<Role>> securityRepository) {
+      this.securityRepository = securityRepository;
+   }
+
+   private void processSearchResult(Map<String, Set<Role>> securityRoles, SearchResult searchResult) throws NamingException {
+      Attributes attrs = searchResult.getAttributes();
+      if (attrs == null || attrs.size() == 0) {
+         return;
+      }
+      LdapName searchResultLdapName = new LdapName(searchResult.getName());
+      ActiveMQServerLogger.LOGGER.debug("LDAP search result : " + searchResultLdapName);
+      String permissionType = null;
+      String destination = null;
+      String destinationType = "unknown";
+      for (Rdn rdn : searchResultLdapName.getRdns()) {
+         if (rdn.getType().equals("cn")) {
+            ActiveMQServerLogger.LOGGER.debug("\tPermission type: " + rdn.getValue());
+            permissionType = rdn.getValue().toString();
+         }
+         if (rdn.getType().equals("uid")) {
+            ActiveMQServerLogger.LOGGER.debug("\tDestination name: " + rdn.getValue());
+            destination = rdn.getValue().toString();
+         }
+         if (rdn.getType().equals("ou")) {
+            String rawDestinationType = rdn.getValue().toString();
+            if (rawDestinationType.toLowerCase().contains("queue")) {
+               destinationType = "queue";
             }
-            LdapName searchResultLdapName = new LdapName(searchResult.getName());
-            ActiveMQServerLogger.LOGGER.debug("LDAP search result " + ++i + ": " + searchResultLdapName);
-            String permissionType = null;
-            String destination = null;
-            String destinationType = "unknown";
-            for (Rdn rdn : searchResultLdapName.getRdns()) {
-               if (rdn.getType().equals("cn")) {
-                  ActiveMQServerLogger.LOGGER.debug("\tPermission type: " + rdn.getValue());
-                  permissionType = rdn.getValue().toString();
-               }
-               if (rdn.getType().equals("uid")) {
-                  ActiveMQServerLogger.LOGGER.debug("\tDestination name: " + rdn.getValue());
-                  destination = rdn.getValue().toString();
-               }
-               if (rdn.getType().equals("ou")) {
-                  String rawDestinationType = rdn.getValue().toString();
-                  if (rawDestinationType.toLowerCase().contains("queue")) {
-                     destinationType = "queue";
-                  }
-                  else if (rawDestinationType.toLowerCase().contains("topic")) {
-                     destinationType = "topic";
-                  }
-                  ActiveMQServerLogger.LOGGER.debug("\tDestination type: " + destinationType);
-               }
+            else if (rawDestinationType.toLowerCase().contains("topic")) {
+               destinationType = "topic";
             }
-            ActiveMQServerLogger.LOGGER.debug("\tAttributes: " + attrs);
-            Attribute attr = attrs.get(roleAttribute);
-            NamingEnumeration<?> e = attr.getAll();
-            Set<Role> roles = securityRoles.get(destination);
-            boolean exists = false;
-            if (roles == null) {
-               roles = new HashSet<>();
+            ActiveMQServerLogger.LOGGER.debug("\tDestination type: " + destinationType);
+         }
+      }
+      ActiveMQServerLogger.LOGGER.debug("\tAttributes: " + attrs);
+      Attribute attr = attrs.get(roleAttribute);
+      NamingEnumeration<?> e = attr.getAll();
+      Set<Role> roles = securityRoles.get(destination);
+      boolean exists = false;
+      if (roles == null) {
+         roles = new HashSet<>();
+      }
+      else {
+         exists = true;
+      }
+
+      while (e.hasMore()) {
+         String value = (String) e.next();
+         LdapName ldapname = new LdapName(value);
+         Rdn rdn = ldapname.getRdn(ldapname.size() - 1);
+         String roleName = rdn.getValue().toString();
+         ActiveMQServerLogger.LOGGER.debug("\tRole name: " + roleName);
+         Role role = new Role(roleName,
+                              permissionType.equalsIgnoreCase(writePermissionValue),
+                              permissionType.equalsIgnoreCase(readPermissionValue),
+                              permissionType.equalsIgnoreCase(adminPermissionValue),
+                              permissionType.equalsIgnoreCase(adminPermissionValue),
+                              permissionType.equalsIgnoreCase(adminPermissionValue),
+                              permissionType.equalsIgnoreCase(adminPermissionValue),
+                              false); // there is no permission from ActiveMQ 5.x that corresponds to the "manage" permission in ActiveMQ Artemis
+         roles.add(role);
+      }
+
+      if (!exists) {
+         securityRoles.put(destination, roles);
+      }
+   }
+
+   public SecuritySettingPlugin stop() {
+      try {
+         eventContext.close();
+      }
+      catch (NamingException e) {
+         // ignore
+      }
+
+      try {
+         context.close();
+      }
+      catch (NamingException e) {
+         // ignore
+      }
+
+      return this;
+   }
+
+   /**
+    * Handler for new policy entries in the directory.
+    *
+    * @param namingEvent
+    *            the new entry event that occurred
+    */
+   public void objectAdded(NamingEvent namingEvent) {
+      Map<String, Set<Role>> newRoles = new HashMap<>();
+
+      try {
+         processSearchResult(newRoles, (SearchResult) namingEvent.getNewBinding());
+         for (Map.Entry<String, Set<Role>> entry : newRoles.entrySet()) {
+            Set<Role> existingRoles = securityRepository.getMatch(entry.getKey());
+            for (Role role : entry.getValue()) {
+               existingRoles.add(role);
             }
-            else {
-               exists = true;
+         }
+      }
+      catch (NamingException e) {
+         e.printStackTrace();
+      }
+   }
+
+   /**
+    * Handler for removed policy entries in the directory.
+    *
+    * @param namingEvent
+    *            the removed entry event that occurred
+    */
+   public void objectRemoved(NamingEvent namingEvent) {
+      try {
+         LdapName ldapName = new LdapName(namingEvent.getOldBinding().getName());
+         String match = null;
+         for (Rdn rdn : ldapName.getRdns()) {
+            if (rdn.getType().equals("uid")) {
+               match = rdn.getValue().toString();
             }
+         }
 
-            while (e.hasMore()) {
-               String value = (String) e.next();
-               LdapName ldapname = new LdapName(value);
-               Rdn rdn = ldapname.getRdn(ldapname.size() - 1);
-               String roleName = rdn.getValue().toString();
-               ActiveMQServerLogger.LOGGER.debug("\tRole name: " + roleName);
-               Role role = new Role(roleName,
-                                    permissionType.equalsIgnoreCase(writePermissionValue),
-                                    permissionType.equalsIgnoreCase(readPermissionValue),
-                                    permissionType.equalsIgnoreCase(adminPermissionValue),
-                                    permissionType.equalsIgnoreCase(adminPermissionValue),
-                                    permissionType.equalsIgnoreCase(adminPermissionValue),
-                                    permissionType.equalsIgnoreCase(adminPermissionValue),
-                                    false); // there is no permission from ActiveMQ 5.x that corresponds to the "manage" permission in ActiveMQ Artemis
-               roles.add(role);
+         Set<Role> roles = securityRepository.getMatch(match);
+
+         List<Role> rolesToRemove = new ArrayList<>();
+
+         for (Rdn rdn : ldapName.getRdns()) {
+            if (rdn.getValue().equals(writePermissionValue)) {
+               ActiveMQServerLogger.LOGGER.debug("Removing write permission");
+               for (Role role : roles) {
+                  if (role.isSend()) {
+                     rolesToRemove.add(role);
+                  }
+               }
+            }
+            else if (rdn.getValue().equals(readPermissionValue)) {
+               ActiveMQServerLogger.LOGGER.debug("Removing read permission");
+               for (Role role : roles) {
+                  if (role.isConsume()) {
+                     rolesToRemove.add(role);
+                  }
+               }
+            }
+            else if (rdn.getValue().equals(adminPermissionValue)) {
+               ActiveMQServerLogger.LOGGER.debug("Removing admin permission");
+               for (Role role : roles) {
+                  if (role.isCreateDurableQueue() || role.isCreateNonDurableQueue() || role.isDeleteDurableQueue() || role.isDeleteNonDurableQueue()) {
+                     rolesToRemove.add(role);
+                  }
+               }
             }
 
-            if (!exists) {
-               securityRoles.put(destination, roles);
+            for (Role roleToRemove : rolesToRemove) {
+               roles.remove(roleToRemove);
             }
          }
       }
-      catch (Exception e) {
-         ActiveMQServerLogger.LOGGER.errorPopulatingSecurityRolesFromLDAP(e);
+      catch (NamingException e) {
+         e.printStackTrace();
       }
+   }
 
-      this.securityRoles = securityRoles;
-      return this;
+   /**
+    * @param namingEvent
+    *            the renaming entry event that occurred
+    */
+   public void objectRenamed(NamingEvent namingEvent) {
+
+   }
+
+   /**
+    * Handler for changed policy entries in the directory.
+    *
+    * @param namingEvent
+    *            the changed entry event that occurred
+    */
+   public void objectChanged(NamingEvent namingEvent) {
+      objectRemoved(namingEvent);
+      objectAdded(namingEvent);
+   }
+
+   /**
+    * Handler for exception events from the registry.
+    *
+    * @param namingExceptionEvent
+    *            the exception event
+    */
+   public void namingExceptionThrown(NamingExceptionEvent namingExceptionEvent) {
+      context = null;
+      ActiveMQServerLogger.LOGGER.error("Caught unexpected exception.", namingExceptionEvent.getException());
+   }
+
+   protected class LDAPNamespaceChangeListener implements NamespaceChangeListener, ObjectChangeListener {
+      @Override
+      public void namingExceptionThrown(NamingExceptionEvent evt) {
+         LegacyLDAPSecuritySettingPlugin.this.namingExceptionThrown(evt);
+      }
+
+      @Override
+      public void objectAdded(NamingEvent evt) {
+         LegacyLDAPSecuritySettingPlugin.this.objectAdded(evt);
+      }
+
+      @Override
+      public void objectRemoved(NamingEvent evt) {
+         LegacyLDAPSecuritySettingPlugin.this.objectRemoved(evt);
+      }
+
+      @Override
+      public void objectRenamed(NamingEvent evt) {
+         LegacyLDAPSecuritySettingPlugin.this.objectRenamed(evt);
+      }
+
+      @Override
+      public void objectChanged(NamingEvent evt) {
+         LegacyLDAPSecuritySettingPlugin.this.objectChanged(evt);
+      }
    }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/artemis-server/src/main/resources/schema/artemis-configuration.xsd
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/resources/schema/artemis-configuration.xsd b/artemis-server/src/main/resources/schema/artemis-configuration.xsd
index 9174019..8703e7b 100644
--- a/artemis-server/src/main/resources/schema/artemis-configuration.xsd
+++ b/artemis-server/src/main/resources/schema/artemis-configuration.xsd
@@ -698,7 +698,7 @@
                </xsd:documentation>
             </xsd:annotation>
             <xsd:complexType>
-               <xsd:sequence>
+               <xsd:choice>
                   <xsd:element name="security-setting" maxOccurs="unbounded" minOccurs="0">
                      <xsd:complexType>
                         <xsd:annotation>
@@ -735,7 +735,7 @@
                         </xsd:attribute>
                      </xsd:complexType>
                   </xsd:element>
-                  <xsd:element name="security-setting-plugin" maxOccurs="unbounded" minOccurs="0">
+                  <xsd:element name="security-setting-plugin" maxOccurs="1" minOccurs="0">
                      <xsd:complexType>
                         <xsd:annotation>
                            <xsd:documentation>
@@ -771,7 +771,7 @@
                         </xsd:attribute>
                      </xsd:complexType>
                   </xsd:element>
-               </xsd:sequence>
+               </xsd:choice>
             </xsd:complexType>
          </xsd:element>
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationParserTest.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationParserTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationParserTest.java
index 99a45ef..84441a2 100644
--- a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationParserTest.java
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationParserTest.java
@@ -16,6 +16,11 @@
  */
 package org.apache.activemq.artemis.core.config.impl;
 
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
 import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
 import org.apache.activemq.artemis.core.config.Configuration;
 import org.apache.activemq.artemis.core.config.FileDeploymentManager;
@@ -24,11 +29,6 @@ import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.apache.activemq.artemis.utils.DefaultSensitiveStringCodec;
 import org.junit.Test;
 
-import java.io.ByteArrayInputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
-
 public class FileConfigurationParserTest extends ActiveMQTestBase {
 
    /**
@@ -43,7 +43,7 @@ public class FileConfigurationParserTest extends ActiveMQTestBase {
     */
    @Test
    public void testSchemaValidation() throws Exception {
-      for (int i = 0; i < 6; i++) {
+      for (int i = 0; i < 7; i++) {
          String filename = "InvalidConfigurationTest" + i + ".xml";
          FileConfiguration fc = new FileConfiguration();
          FileDeploymentManager deploymentManager = new FileDeploymentManager(filename);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java
index 587d281..c4831bc 100644
--- a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java
@@ -24,6 +24,8 @@ import java.nio.file.Path;
 import java.nio.file.StandardCopyOption;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.activemq.artemis.api.core.BroadcastGroupConfiguration;
 import org.apache.activemq.artemis.api.core.DiscoveryGroupConfiguration;
@@ -316,13 +318,15 @@ public class FileConfigurationTest extends ConfigurationImplTest {
       assertEquals("color='blue'", conf.getQueueConfigurations().get(1).getFilterString());
       assertEquals(false, conf.getQueueConfigurations().get(1).isDurable());
 
-      assertEquals(2, conf.getSecurityRoles().size());
+      Map<String, Set<Role>> roles = conf.getSecurityRoles();
 
-      assertTrue(conf.getSecurityRoles().containsKey("a1"));
+      assertEquals(2, roles.size());
 
-      assertTrue(conf.getSecurityRoles().containsKey("a2"));
+      assertTrue(roles.containsKey("a1"));
 
-      Role a1Role = conf.getSecurityRoles().get("a1").toArray(new Role[1])[0];
+      assertTrue(roles.containsKey("a2"));
+
+      Role a1Role = roles.get("a1").toArray(new Role[1])[0];
 
       assertFalse(a1Role.isSend());
       assertFalse(a1Role.isConsume());
@@ -332,7 +336,7 @@ public class FileConfigurationTest extends ConfigurationImplTest {
       assertFalse(a1Role.isDeleteNonDurableQueue());
       assertFalse(a1Role.isManage());
 
-      Role a2Role = conf.getSecurityRoles().get("a2").toArray(new Role[1])[0];
+      Role a2Role = roles.get("a2").toArray(new Role[1])[0];
 
       assertFalse(a2Role.isSend());
       assertFalse(a2Role.isConsume());
@@ -341,8 +345,16 @@ public class FileConfigurationTest extends ConfigurationImplTest {
       assertFalse(a2Role.isCreateNonDurableQueue());
       assertTrue(a2Role.isDeleteNonDurableQueue());
       assertFalse(a2Role.isManage());
+   }
+
+   @Test
+   public void testSecuritySettingPlugin() throws Exception {
+      FileConfiguration fc = new FileConfiguration();
+      FileDeploymentManager deploymentManager = new FileDeploymentManager("securitySettingPlugin.xml");
+      deploymentManager.addDeployable(fc);
+      deploymentManager.readConfiguration();
 
-      List<SecuritySettingPlugin> securitySettingPlugins = conf.getSecuritySettingPlugins();
+      List<SecuritySettingPlugin> securitySettingPlugins = fc.getSecuritySettingPlugins();
       SecuritySettingPlugin securitySettingPlugin = securitySettingPlugins.get(0);
       assertTrue(securitySettingPlugin instanceof LegacyLDAPSecuritySettingPlugin);
       LegacyLDAPSecuritySettingPlugin legacyLDAPSecuritySettingPlugin = (LegacyLDAPSecuritySettingPlugin) securitySettingPlugin;
@@ -358,6 +370,7 @@ public class FileConfigurationTest extends ConfigurationImplTest {
       assertEquals(legacyLDAPSecuritySettingPlugin.getAdminPermissionValue(), "testAdminPermissionValue");
       assertEquals(legacyLDAPSecuritySettingPlugin.getReadPermissionValue(), "testReadPermissionValue");
       assertEquals(legacyLDAPSecuritySettingPlugin.getWritePermissionValue(), "testWritePermissionValue");
+      assertEquals(legacyLDAPSecuritySettingPlugin.isEnableListener(), false);
    }
 
    @Test

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/resources/ConfigurationTest-full-config.xml b/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
index 5c4a0a2..0514788 100644
--- a/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
+++ b/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
@@ -232,20 +232,6 @@
          <security-setting match="a2">
             <permission type="deleteNonDurableQueue" roles="a2.1"/>
          </security-setting>
-         <security-setting-plugin class-name="org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin">
-            <setting name="initialContextFactory" value="testInitialContextFactory"/>
-            <setting name="connectionURL" value="testConnectionURL"/>
-            <setting name="connectionUsername" value="testConnectionUsername"/>
-            <setting name="connectionPassword" value="testConnectionPassword"/>
-            <setting name="connectionProtocol" value="testConnectionProtocol"/>
-            <setting name="authentication" value="testAuthentication"/>
-            <setting name="destinationBase" value="testDestinationBase"/>
-            <setting name="filter" value="testFilter"/>
-            <setting name="roleAttribute" value="testRoleAttribute"/>
-            <setting name="adminPermissionValue" value="testAdminPermissionValue"/>
-            <setting name="readPermissionValue" value="testReadPermissionValue"/>
-            <setting name="writePermissionValue" value="testWritePermissionValue"/>
-         </security-setting-plugin>
       </security-settings>
 
       <address-settings>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/artemis-server/src/test/resources/InvalidConfigurationTest6.xml
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/resources/InvalidConfigurationTest6.xml b/artemis-server/src/test/resources/InvalidConfigurationTest6.xml
new file mode 100644
index 0000000..db3799a
--- /dev/null
+++ b/artemis-server/src/test/resources/InvalidConfigurationTest6.xml
@@ -0,0 +1,45 @@
+<!--
+  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.
+-->
+<configuration
+      xmlns="urn:activemq"
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xsi:schemaLocation="urn:activemq ../../src/config/common/schema/artemis-server.xsd">
+   <core xmlns="urn:activemq:core">
+      <security-settings>
+         <security-setting match="a1">
+            <permission type="createNonDurableQueue" roles="a1.1"/>
+         </security-setting>
+         <security-setting match="a2">
+            <permission type="deleteNonDurableQueue" roles="a2.1"/>
+         </security-setting>
+         <security-setting-plugin class-name="org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin">
+            <setting name="initialContextFactory" value="testInitialContextFactory"/>
+            <setting name="connectionURL" value="testConnectionURL"/>
+            <setting name="connectionUsername" value="testConnectionUsername"/>
+            <setting name="connectionPassword" value="testConnectionPassword"/>
+            <setting name="connectionProtocol" value="testConnectionProtocol"/>
+            <setting name="authentication" value="testAuthentication"/>
+            <setting name="destinationBase" value="testDestinationBase"/>
+            <setting name="filter" value="testFilter"/>
+            <setting name="roleAttribute" value="testRoleAttribute"/>
+            <setting name="adminPermissionValue" value="testAdminPermissionValue"/>
+            <setting name="readPermissionValue" value="testReadPermissionValue"/>
+            <setting name="writePermissionValue" value="testWritePermissionValue"/>
+         </security-setting-plugin>
+      </security-settings>
+   </core>
+</configuration>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/artemis-server/src/test/resources/securitySettingPlugin.xml
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/resources/securitySettingPlugin.xml b/artemis-server/src/test/resources/securitySettingPlugin.xml
new file mode 100644
index 0000000..25207d5
--- /dev/null
+++ b/artemis-server/src/test/resources/securitySettingPlugin.xml
@@ -0,0 +1,40 @@
+<!--
+  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.
+-->
+<configuration
+      xmlns="urn:activemq"
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xsi:schemaLocation="urn:activemq ../../../../activemq-server/src/main/resources/schema/artemis-server.xsd">
+   <core xmlns="urn:activemq:core">
+      <security-settings>
+         <security-setting-plugin class-name="org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin">
+            <setting name="initialContextFactory" value="testInitialContextFactory"/>
+            <setting name="connectionURL" value="testConnectionURL"/>
+            <setting name="connectionUsername" value="testConnectionUsername"/>
+            <setting name="connectionPassword" value="testConnectionPassword"/>
+            <setting name="connectionProtocol" value="testConnectionProtocol"/>
+            <setting name="authentication" value="testAuthentication"/>
+            <setting name="destinationBase" value="testDestinationBase"/>
+            <setting name="filter" value="testFilter"/>
+            <setting name="roleAttribute" value="testRoleAttribute"/>
+            <setting name="adminPermissionValue" value="testAdminPermissionValue"/>
+            <setting name="readPermissionValue" value="testReadPermissionValue"/>
+            <setting name="writePermissionValue" value="testWritePermissionValue"/>
+            <setting name="enableListener" value="false"/>
+         </security-setting-plugin>
+      </security-settings>
+   </core>
+</configuration>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/docs/user-manual/en/security.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/security.md b/docs/user-manual/en/security.md
index 5bb3372..f6e654d 100644
--- a/docs/user-manual/en/security.md
+++ b/docs/user-manual/en/security.md
@@ -122,12 +122,10 @@ in sub-groups of addresses.
 
 ## Security Setting Plugin
 
-Aside from configuring sets of permissions via XML these permissions can also be
-configured via plugins which implement `org.apache.activemq.artemis.core.server.SecuritySettingPlugin`.
-One or more plugins can be defined and configured alongside the normal XML, e.g.:
+Aside from configuring sets of permissions via XML these permissions can alternatively be
+configured via a plugin which implements `org.apache.activemq.artemis.core.server.SecuritySettingPlugin` e.g.:
 
     <security-settings>
-       ...
        <security-setting-plugin class-name="org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin">
           <setting name="initialContextFactory" value="com.sun.jndi.ldap.LdapCtxFactory"/>
           <setting name="connectionURL" value="ldap://localhost:1024"/>
@@ -210,6 +208,9 @@ Here is an example of the plugin's configuration:
 
 -   `writePermissionValue`. Specifies a value that matches the `write` permission. The default value is `write`.
 
+-   `enableListener`. Whether or not to enable a listener that will automatically receive updates made in the LDAP server
+    and update the broker's authorization configuration in real-time. The default value is `true`.
+
 The name of the queue or topic defined in LDAP will serve as the "match" for the security-setting, the permission value
 will be mapped from the ActiveMQ 5.x type to the Artemis type, and the role will be mapped as-is. It's worth noting that
 since the name of queue or topic coming from LDAP will server as the "match" for the security-setting the security-setting
@@ -254,46 +255,12 @@ This is the default security manager.
 
 -   The flexible, pluggable `ActiveMQJAASSecurityManager` which supports any standard JAAS login module. Artemis ships 
 with several login modules which will be discussed further down. 
-
-### Non-JAAS Security Manager
-
-If you wish to use the legacy, deprecated `ActiveMQSecurityManager`, then it needs to be added to the `bootstrap.xml` 
-configuration. Lets take a look at what this might look like:
-
-    <basic-security>
-      <users>file:${activemq.home}/config/non-clustered/artemis-users.properties</users>
-      <roles>file:${activemq.home}/config/non-clustered/artemis-roles.properties</roles>
-      <default-user>guest</default-user>
-    </basic-security>
-
-The first 2 elements `users` and `roles` define what properties files should be used to load in the users and passwords.
-
-The next thing to note is the element `defaultuser`. This defines what user will be assumed when the client does not 
-specify a username/password when creating a session. In this case they will be the user `guest`. Multiple roles can be 
-specified for a default user in the `artemis-roles.properties`.
-
-Lets now take a look at the `artemis-users.properties` file, this is basically just a set of key value pairs that define
-the users and their password, like so:
-
-    bill=activemq
-    andrew=activemq1
-    frank=activemq2
-    sam=activemq3
-
-The `artemis-roles.properties` defines what groups these users belong too where the key is the user and the value is a 
-comma separated list of the groups the user belongs to, like so:
-
-    bill=user
-    andrew=europe-user,user
-    frank=us-user,news-user,user
-    sam=news-user,user
     
 ### JAAS Security Manager
 
 When using JAAS much of the configuration depends on which login module is used. However, there are a few commonalities
-for every case. Just like in the non-JAAS use-case, the first place to look is in `bootstrap.xml`. Here is an example
-using the `PropertiesLogin` JAAS login module which reads user, password, and role information from properties files
-much like the non-JAAS security manager implementation:
+for every case. The first place to look is in `bootstrap.xml`. Here is an example using the `PropertiesLogin` JAAS login 
+module which reads user, password, and role information from properties files:
 
     <jaas-security domain="PropertiesLogin"/>
     

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/openwire/OpenWireTestBase.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/openwire/OpenWireTestBase.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/openwire/OpenWireTestBase.java
index 275fad6..6a95bfc 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/openwire/OpenWireTestBase.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/openwire/OpenWireTestBase.java
@@ -20,10 +20,8 @@ import javax.jms.ConnectionFactory;
 import javax.management.MBeanServer;
 import javax.management.MBeanServerFactory;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 import org.apache.activemq.artemis.api.core.SimpleString;
@@ -98,20 +96,13 @@ public class OpenWireTestBase extends ActiveMQTestBase {
          //guest cannot do anything
          Role destRole = new Role("manager", false, false, false, false, true, true, false);
 
-         Map<String, Set<Role>> settings = server.getConfiguration().getSecurityRoles();
-         if (settings == null) {
-            settings = new HashMap<>();
-            server.getConfiguration().setSecurityRoles(settings);
-         }
-         Set<Role> anySet = settings.get("#");
-         if (anySet == null) {
-            anySet = new HashSet<>();
-            settings.put("#", anySet);
-         }
-         anySet.add(senderRole);
-         anySet.add(receiverRole);
-         anySet.add(guestRole);
-         anySet.add(destRole);
+         Set<Role> roles =  new HashSet<>();
+         roles.add(senderRole);
+         roles.add(receiverRole);
+         roles.add(guestRole);
+         roles.add(destRole);
+
+         server.getConfiguration().putSecurityRoles("#", roles);
       }
       jmsServer = new JMSServerManagerImpl(server);
       namingContext = new InVMNamingContext();

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/LDAPSecurityTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/LDAPSecurityTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/LDAPSecurityTest.java
index e37414e..41f6ab9 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/LDAPSecurityTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/LDAPSecurityTest.java
@@ -172,7 +172,7 @@ public class LDAPSecurityTest extends AbstractLdapTestUnit {
       ActiveMQServer server = getActiveMQServer();
       Set<Role> roles = new HashSet<>();
       roles.add(new Role("programmers", false, false, false, false, false, false, false));
-      server.getConfiguration().getSecurityRoles().put("#", roles);
+      server.getConfiguration().putSecurityRoles("#", roles);
       server.start();
       server.createQueue(ADDRESS, DURABLE_QUEUE, null, true, false);
       server.createQueue(ADDRESS, NON_DURABLE_QUEUE, null, false, false);
@@ -260,7 +260,7 @@ public class LDAPSecurityTest extends AbstractLdapTestUnit {
       ActiveMQServer server = getActiveMQServer();
       Set<Role> roles = new HashSet<>();
       roles.add(new Role("admins", true, true, true, true, true, true, true));
-      server.getConfiguration().getSecurityRoles().put("#", roles);
+      server.getConfiguration().putSecurityRoles("#", roles);
       server.start();
 
       ClientSessionFactory cf = locator.createSessionFactory();

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/LegacyLDAPSecuritySettingPluginListenerTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/LegacyLDAPSecuritySettingPluginListenerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/LegacyLDAPSecuritySettingPluginListenerTest.java
new file mode 100644
index 0000000..8f237ab
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/LegacyLDAPSecuritySettingPluginListenerTest.java
@@ -0,0 +1,352 @@
+/*
+ * 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.security;
+
+import javax.naming.Context;
+import javax.naming.NameClassPair;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import java.io.File;
+import java.lang.management.ManagementFactory;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
+import org.apache.activemq.artemis.api.core.client.ClientConsumer;
+import org.apache.activemq.artemis.api.core.client.ClientProducer;
+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.config.Configuration;
+import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
+import org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory;
+import org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.core.server.ActiveMQServers;
+import org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.annotations.ApplyLdifFiles;
+import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
+import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+
+@RunWith(FrameworkRunner.class)
+@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP", port = 1024)})
+@ApplyLdifFiles("AMQauth.ldif")
+public class LegacyLDAPSecuritySettingPluginListenerTest extends AbstractLdapTestUnit {
+
+   static {
+      String path = System.getProperty("java.security.auth.login.config");
+      if (path == null) {
+         URL resource = LegacyLDAPSecuritySettingPluginListenerTest.class.getClassLoader().getResource("login.config");
+         if (resource != null) {
+            path = resource.getFile();
+            System.setProperty("java.security.auth.login.config", path);
+         }
+      }
+   }
+
+   private ServerLocator locator;
+
+   public static final String TARGET_TMP = "./target/tmp";
+   private static final String PRINCIPAL = "uid=admin,ou=system";
+   private static final String CREDENTIALS = "secret";
+
+
+   public LegacyLDAPSecuritySettingPluginListenerTest() {
+      File parent = new File(TARGET_TMP);
+      parent.mkdirs();
+      temporaryFolder = new TemporaryFolder(parent);
+   }
+
+   @Rule
+   public TemporaryFolder temporaryFolder;
+   private String testDir;
+
+   @Before
+   public void setUp() throws Exception {
+      locator = ActiveMQClient.createServerLocatorWithHA(new TransportConfiguration(InVMConnectorFactory.class.getCanonicalName()));
+      testDir = temporaryFolder.getRoot().getAbsolutePath();
+   }
+
+   @SuppressWarnings("unchecked")
+   @Test
+   public void testRunning() throws Exception {
+      DirContext ctx = getContext();
+
+      HashSet set = new HashSet();
+
+      NamingEnumeration list = ctx.list("ou=system");
+
+      while (list.hasMore()) {
+         NameClassPair ncp = (NameClassPair) list.next();
+         set.add(ncp.getName());
+      }
+
+      Assert.assertTrue(set.contains("uid=admin"));
+      Assert.assertTrue(set.contains("ou=users"));
+      Assert.assertTrue(set.contains("ou=groups"));
+      Assert.assertTrue(set.contains("ou=configuration"));
+      Assert.assertTrue(set.contains("prefNodeName=sysPrefRoot"));
+   }
+
+   private DirContext getContext() throws NamingException {
+      Hashtable env = new Hashtable();
+      env.put(Context.PROVIDER_URL, "ldap://localhost:1024");
+      env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+      env.put(Context.SECURITY_AUTHENTICATION, "simple");
+      env.put(Context.SECURITY_PRINCIPAL, PRINCIPAL);
+      env.put(Context.SECURITY_CREDENTIALS, CREDENTIALS);
+      return new InitialDirContext(env);
+   }
+
+   @Test
+   public void testProducerPermissionUpdate() throws Exception {
+      ActiveMQServer server = getActiveMQServer();
+      server.getConfiguration().setSecurityInvalidationInterval(0);
+      server.start();
+      ClientSessionFactory cf = locator.createSessionFactory();
+      String name = "queue1";
+      ClientSession session = cf.createSession("first", "secret", false, true, true, false, 0);
+      ClientSession session2 = cf.createSession("second", "secret", false, true, true, false, 0);
+      session.createQueue(SimpleString.toSimpleString(name), SimpleString.toSimpleString(name));
+      ClientProducer producer = session.createProducer();
+      ClientProducer producer2 = session2.createProducer();
+      producer.send(name, session.createMessage(true));
+
+      try {
+         producer2.send(name, session.createMessage(true));
+         Assert.fail("Sending here should fail due to the original security data.");
+      }
+      catch (ActiveMQException e) {
+         // ok
+      }
+
+      DirContext ctx = getContext();
+      BasicAttributes basicAttributes = new BasicAttributes();
+      basicAttributes.put("uniquemember", "uid=role2");
+      ctx.modifyAttributes("cn=write,uid=queue1,ou=queues,ou=destinations,o=ActiveMQ,ou=system", DirContext.REPLACE_ATTRIBUTE, basicAttributes);
+
+      producer2.send(name, session.createMessage(true));
+
+      try {
+         producer.send(name, session.createMessage(true));
+         Assert.fail("Sending here should fail due to the modified security data.");
+      }
+      catch (ActiveMQException e) {
+         // ok
+      }
+
+      cf.close();
+      locator.close();
+      server.stop();
+   }
+
+   @Test
+   public void testConsumerPermissionUpdate() throws Exception {
+      ActiveMQServer server = getActiveMQServer();
+      server.getConfiguration().setSecurityInvalidationInterval(0);
+      server.start();
+      ClientSessionFactory cf = locator.createSessionFactory();
+      String queue = "queue1";
+      ClientSession session = cf.createSession("first", "secret", false, true, true, false, 0);
+      ClientSession session2 = cf.createSession("second", "secret", false, true, true, false, 0);
+      session.createQueue(SimpleString.toSimpleString(queue), SimpleString.toSimpleString(queue));
+      ClientConsumer consumer = session.createConsumer(queue);
+      consumer.receiveImmediate();
+      consumer.close();
+      ClientConsumer consumer2 = null;
+
+      try {
+         session2.createConsumer(queue);
+         Assert.fail("Consuming here should fail due to the original security data.");
+      }
+      catch (ActiveMQException e) {
+         // ok
+      }
+
+      DirContext ctx = getContext();
+      BasicAttributes basicAttributes = new BasicAttributes();
+      basicAttributes.put("uniquemember", "uid=role2");
+      ctx.modifyAttributes("cn=read,uid=queue1,ou=queues,ou=destinations,o=ActiveMQ,ou=system", DirContext.REPLACE_ATTRIBUTE, basicAttributes);
+
+      consumer2 = session2.createConsumer(queue);
+      consumer2.receiveImmediate();
+      consumer2.close();
+
+      try {
+         session.createConsumer(queue);
+         Assert.fail("Sending here should fail due to the modified security data.");
+      }
+      catch (ActiveMQException e) {
+         // ok
+      }
+
+      cf.close();
+      locator.close();
+      server.stop();
+   }
+
+   @Test
+   public void testNewConsumerPermission() throws Exception {
+      ActiveMQServer server = getActiveMQServer();
+      server.getConfiguration().setSecurityInvalidationInterval(0);
+      server.start();
+      String queue = "queue2";
+      server.createQueue(SimpleString.toSimpleString(queue), SimpleString.toSimpleString(queue), null, false, false);
+      ClientSessionFactory cf = locator.createSessionFactory();
+      ClientSession session = cf.createSession("first", "secret", false, true, true, false, 0);
+      ClientConsumer consumer;
+
+      try {
+         session.createConsumer(queue);
+         Assert.fail("Consuming here should fail due to the original security data.");
+      }
+      catch (ActiveMQException e) {
+         // ok
+      }
+
+      DirContext ctx = getContext();
+      BasicAttributes basicAttributes = new BasicAttributes();
+      basicAttributes.put("uniquemember", "uid=role1");
+      Attribute objclass = new BasicAttribute("objectclass");
+      objclass.add("top");
+      objclass.add("groupOfUniqueNames");
+      basicAttributes.put(objclass);
+      ctx.bind("cn=read,uid=" + queue + ",ou=queues,ou=destinations,o=ActiveMQ,ou=system", null, basicAttributes);
+
+      consumer = session.createConsumer(queue);
+      consumer.receiveImmediate();
+
+      ctx.unbind("cn=read,uid=" + queue + ",ou=queues,ou=destinations,o=ActiveMQ,ou=system");
+      ctx.close();
+
+      try {
+         session.createConsumer(queue);
+         Assert.fail("Consuming here should fail due to the modified security data.");
+      }
+      catch (ActiveMQException e) {
+         // ok
+      }
+
+      consumer.close();
+
+      cf.close();
+      locator.close();
+      server.stop();
+   }
+
+   @Test
+   public void testNewProducerPermission() throws Exception {
+      ActiveMQServer server = getActiveMQServer();
+      server.getConfiguration().setSecurityInvalidationInterval(0);
+      server.start();
+      String queue = "queue2";
+      server.createQueue(SimpleString.toSimpleString(queue), SimpleString.toSimpleString(queue), null, false, false);
+      ClientSessionFactory cf = locator.createSessionFactory();
+      ClientSession session = cf.createSession("first", "secret", false, true, true, false, 0);
+      ClientProducer producer = session.createProducer(SimpleString.toSimpleString(queue));
+
+      try {
+         producer.send(session.createMessage(true));
+         Assert.fail("Producing here should fail due to the original security data.");
+      }
+      catch (ActiveMQException e) {
+         // ok
+      }
+
+      DirContext ctx = getContext();
+      BasicAttributes basicAttributes = new BasicAttributes();
+      basicAttributes.put("uniquemember", "uid=role1");
+      Attribute objclass = new BasicAttribute("objectclass");
+      objclass.add("top");
+      objclass.add("groupOfUniqueNames");
+      basicAttributes.put(objclass);
+      ctx.bind("cn=write,uid=" + queue + ",ou=queues,ou=destinations,o=ActiveMQ,ou=system", null, basicAttributes);
+
+      producer.send(session.createMessage(true));
+
+      ctx.unbind("cn=write,uid=" + queue + ",ou=queues,ou=destinations,o=ActiveMQ,ou=system");
+      ctx.close();
+
+      try {
+         producer.send(session.createMessage(true));
+         Assert.fail("Producing here should fail due to the modified security data.");
+      }
+      catch (ActiveMQException e) {
+         // ok
+      }
+
+      producer.close();
+
+      cf.close();
+      locator.close();
+      server.stop();
+   }
+
+   private ActiveMQServer getActiveMQServer() {
+      LegacyLDAPSecuritySettingPlugin legacyLDAPSecuritySettingPlugin = new LegacyLDAPSecuritySettingPlugin();
+      Map<String, String> map = new HashMap<>();
+      map.put(LegacyLDAPSecuritySettingPlugin.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+      map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_URL, "ldap://localhost:1024");
+      map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_USERNAME, "uid=admin,ou=system");
+      map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_PASSWORD, "secret");
+      map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_PROTOCOL, "s");
+      map.put(LegacyLDAPSecuritySettingPlugin.AUTHENTICATION, "simple");
+      map.put(LegacyLDAPSecuritySettingPlugin.ENABLE_LISTENER, "true");
+      legacyLDAPSecuritySettingPlugin.init(map);
+//         .setInitialContextFactory("com.sun.jndi.ldap.LdapCtxFactory")
+//         .setConnectionURL("ldap://localhost:1024")
+//         .setConnectionUsername("uid=admin,ou=system")
+//         .setConnectionPassword("secret")
+//         .setConnectionProtocol("s")
+//         .setAuthentication("simple")
+//         .setEnableListener(true);
+
+      ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager("LDAPLogin");
+      Configuration configuration = new ConfigurationImpl()
+         .setSecurityEnabled(true)
+         .addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getCanonicalName()))
+         .setJournalDirectory(ActiveMQTestBase.getJournalDir(testDir, 0, false))
+         .setBindingsDirectory(ActiveMQTestBase.getBindingsDir(testDir, 0, false))
+         .setPagingDirectory(ActiveMQTestBase.getPageDir(testDir, 0, false))
+         .setLargeMessagesDirectory(ActiveMQTestBase.getLargeMessagesDir(testDir, 0, false))
+         .setPersistenceEnabled(false)
+         .addSecuritySettingPlugin(legacyLDAPSecuritySettingPlugin);
+
+      return ActiveMQServers.newActiveMQServer(configuration, ManagementFactory.getPlatformMBeanServer(), securityManager, false);
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/LegacyLDAPSecuritySettingPluginTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/LegacyLDAPSecuritySettingPluginTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/LegacyLDAPSecuritySettingPluginTest.java
index 48f98bb..672d4c9 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/LegacyLDAPSecuritySettingPluginTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/LegacyLDAPSecuritySettingPluginTest.java
@@ -297,8 +297,7 @@ public class LegacyLDAPSecuritySettingPluginTest extends AbstractLdapTestUnit {
          .setConnectionUsername("uid=admin,ou=system")
          .setConnectionPassword("secret")
          .setConnectionProtocol("s")
-         .setAuthentication("simple")
-         .populateSecurityRoles();
+         .setAuthentication("simple");
 
       ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager("LDAPLogin");
       Configuration configuration = new ConfigurationImpl()

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d94c044e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java
index e5404ef..71cd369 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java
@@ -229,7 +229,7 @@ public class SecurityTest extends ActiveMQTestBase {
       ActiveMQServer server = addServer(ActiveMQServers.newActiveMQServer(createDefaultInVMConfig().setSecurityEnabled(true), ManagementFactory.getPlatformMBeanServer(), securityManager, false));
       Set<Role> roles = new HashSet<>();
       roles.add(new Role("programmers", false, false, false, false, false, false, false));
-      server.getConfiguration().getSecurityRoles().put("#", roles);
+      server.getConfiguration().putSecurityRoles("#", roles);
       server.start();
       server.createQueue(ADDRESS, DURABLE_QUEUE, null, true, false);
       server.createQueue(ADDRESS, NON_DURABLE_QUEUE, null, false, false);
@@ -324,7 +324,7 @@ public class SecurityTest extends ActiveMQTestBase {
 
       Set<Role> roles = new HashSet<>();
       roles.add(new Role("programmers", false, false, false, false, false, false, false));
-      server.getConfiguration().getSecurityRoles().put("#", roles);
+      server.getConfiguration().putSecurityRoles("#", roles);
 
       server.start();
 
@@ -418,7 +418,7 @@ public class SecurityTest extends ActiveMQTestBase {
       ActiveMQServer server = addServer(ActiveMQServers.newActiveMQServer(createDefaultInVMConfig().setSecurityEnabled(true), ManagementFactory.getPlatformMBeanServer(), securityManager, false));
       Set<Role> roles = new HashSet<>();
       roles.add(new Role("programmers", true, true, true, true, true, true, true));
-      server.getConfiguration().getSecurityRoles().put("#", roles);
+      server.getConfiguration().putSecurityRoles("#", roles);
       server.start();
 
       ClientSessionFactory cf = createSessionFactory(locator);
@@ -506,7 +506,7 @@ public class SecurityTest extends ActiveMQTestBase {
 
       Set<Role> roles = new HashSet<>();
       roles.add(new Role("programmers", true, true, true, true, true, true, true));
-      server.getConfiguration().getSecurityRoles().put("#", roles);
+      server.getConfiguration().putSecurityRoles("#", roles);
       server.start();
 
       TransportConfiguration tc = new TransportConfiguration(NETTY_CONNECTOR_FACTORY);
@@ -590,7 +590,7 @@ public class SecurityTest extends ActiveMQTestBase {
       ActiveMQServer server = addServer(ActiveMQServers.newActiveMQServer(createDefaultInVMConfig().setSecurityEnabled(true), ManagementFactory.getPlatformMBeanServer(), securityManager, false));
       Set<Role> roles = new HashSet<>();
       roles.add(new Role("bar", true, true, true, true, true, true, true));
-      server.getConfiguration().getSecurityRoles().put("#", roles);
+      server.getConfiguration().putSecurityRoles("#", roles);
       server.start();
 
       ClientSessionFactory cf = createSessionFactory(locator);