You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by jb...@apache.org on 2017/04/24 16:25:15 UTC

[1/2] activemq-artemis git commit: This closes #1206

Repository: activemq-artemis
Updated Branches:
  refs/heads/master 4edc3297f -> e078666c0


This closes #1206


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

Branch: refs/heads/master
Commit: e078666c0309b1ef911060186f44785257981991
Parents: 4edc329 24e3799
Author: Justin Bertram <jb...@apache.org>
Authored: Mon Apr 24 10:25:08 2017 -0500
Committer: Justin Bertram <jb...@apache.org>
Committed: Mon Apr 24 10:25:08 2017 -0500

----------------------------------------------------------------------
 .../artemis/core/config/Configuration.java      |   4 +
 .../core/config/impl/ConfigurationImpl.java     |  17 +++
 .../deployers/impl/FileConfigurationParser.java |  75 +++++++++-
 .../resources/schema/artemis-configuration.xsd  | 143 +++++++++++--------
 .../core/config/impl/FileConfigurationTest.java |  84 +++++++++++
 .../src/test/resources/securityRoleMappings.xml |  45 ++++++
 6 files changed, 301 insertions(+), 67 deletions(-)
----------------------------------------------------------------------



[2/2] activemq-artemis git commit: ARTEMIS-1116 map ldap roles to local roles

Posted by jb...@apache.org.
ARTEMIS-1116 map ldap roles to local roles

adds general mapping between multiple amq internal roles
and a external roles (e.g. LDAP), configured in broker.xml


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

Branch: refs/heads/master
Commit: 24e37993478a54c3954687f4b332a33faaed3b58
Parents: 4edc329
Author: Stephen Higgs <sh...@redhat.com>
Authored: Tue Apr 18 13:16:30 2017 -0400
Committer: Justin Bertram <jb...@apache.org>
Committed: Mon Apr 24 10:25:08 2017 -0500

----------------------------------------------------------------------
 .../artemis/core/config/Configuration.java      |   4 +
 .../core/config/impl/ConfigurationImpl.java     |  17 +++
 .../deployers/impl/FileConfigurationParser.java |  75 +++++++++-
 .../resources/schema/artemis-configuration.xsd  | 143 +++++++++++--------
 .../core/config/impl/FileConfigurationTest.java |  84 +++++++++++
 .../src/test/resources/securityRoleMappings.xml |  45 ++++++
 6 files changed, 301 insertions(+), 67 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/24e37993/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 30d6668..7dfb1a5 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
@@ -927,6 +927,10 @@ public interface Configuration {
     */
    Map<String, Set<Role>> getSecurityRoles();
 
+   Configuration addSecurityRoleNameMapping(String internalRole, Set<String> externalRoles);
+
+   Map<String, Set<String>> getSecurityRoleNameMappings();
+
    Configuration putSecurityRoles(String match, Set<Role> roles);
 
    Configuration setConnectorServiceConfigurations(List<ConnectorServiceConfiguration> configs);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/24e37993/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 3ab7468..2a538ca 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
@@ -232,6 +232,8 @@ public class ConfigurationImpl implements Configuration, Serializable {
 
    private List<SecuritySettingPlugin> securitySettingPlugins = new ArrayList<>();
 
+   private Map<String, Set<String>> securityRoleNameMappings = new HashMap<>();
+
    protected List<ConnectorServiceConfiguration> connectorServiceConfigurations = new ArrayList<>();
 
    private boolean maskPassword = ActiveMQDefaultConfiguration.isDefaultMaskPassword();
@@ -1294,6 +1296,21 @@ public class ConfigurationImpl implements Configuration, Serializable {
    }
 
    @Override
+   public Configuration addSecurityRoleNameMapping(String internalRole, Set<String> externalRoles) {
+      if (securityRoleNameMappings.containsKey(internalRole)) {
+         securityRoleNameMappings.get(internalRole).addAll(externalRoles);
+      } else {
+         securityRoleNameMappings.put(internalRole, externalRoles);
+      }
+      return this;
+   }
+
+   @Override
+   public Map<String, Set<String>> getSecurityRoleNameMappings() {
+      return securityRoleNameMappings;
+   }
+
+   @Override
    public List<ConnectorServiceConfiguration> getConnectorServiceConfigurations() {
       return this.connectorServiceConfigurations;
    }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/24e37993/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 6f666b6..6f7f9c9 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
@@ -22,6 +22,7 @@ import java.io.Reader;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -94,6 +95,8 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
 
    public static final String SECURITY_PLUGIN_ELEMENT_NAME = "security-setting-plugin";
 
+   public static final String SECURITY_ROLE_MAPPING_NAME = "role-mapping";
+
    private static final String PERMISSION_ELEMENT_NAME = "permission";
 
    private static final String SETTING_ELEMENT_NAME = "setting";
@@ -106,6 +109,10 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
 
    private static final String VALUE_ATTR_NAME = "value";
 
+   private static final String ROLE_FROM_ATTR_NAME = "from";
+
+   private static final String ROLE_TO_ATTR_NAME = "to";
+
    static final String CREATEDURABLEQUEUE_NAME = "createDurableQueue";
 
    private static final String DELETEDURABLEQUEUE_NAME = "deleteDurableQueue";
@@ -618,12 +625,18 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
     */
    private void parseSecurity(final Element e, final Configuration config) {
       NodeList elements = e.getElementsByTagName("security-settings");
-
       if (elements.getLength() != 0) {
          Element node = (Element) elements.item(0);
-         NodeList list = node.getElementsByTagName(SECURITY_ELEMENT_NAME);
+         NodeList list = node.getElementsByTagName(SECURITY_ROLE_MAPPING_NAME);
+         for (int i = 0; i < list.getLength(); i++) {
+            Map<String, Set<String>> roleMappings = parseSecurityRoleMapping(list.item(i));
+            for (Map.Entry<String, Set<String>> roleMapping : roleMappings.entrySet()) {
+               config.addSecurityRoleNameMapping(roleMapping.getKey(), roleMapping.getValue());
+            }
+         }
+         list = node.getElementsByTagName(SECURITY_ELEMENT_NAME);
          for (int i = 0; i < list.getLength(); i++) {
-            Pair<String, Set<Role>> securityItem = parseSecurityRoles(list.item(i));
+            Pair<String, Set<Role>> securityItem = parseSecurityRoles(list.item(i), config.getSecurityRoleNameMappings());
             config.putSecurityRoles(securityItem.getA(), securityItem.getB());
          }
          list = node.getElementsByTagName(SECURITY_PLUGIN_ELEMENT_NAME);
@@ -711,7 +724,7 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
     * @param node
     * @return
     */
-   protected Pair<String, Set<Role>> parseSecurityRoles(final Node node) {
+   protected Pair<String, Set<Role>> parseSecurityRoles(final Node node, final Map<String, Set<String>> roleMappings) {
       final String match = node.getAttributes().getNamedItem("match").getNodeValue();
 
       Set<Role> securityRoles = new HashSet<>();
@@ -737,7 +750,9 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
             final String type = getAttributeValue(child, TYPE_ATTR_NAME);
             final String roleString = getAttributeValue(child, ROLES_ATTR_NAME);
             String[] roles = roleString.split(",");
-            for (String role : roles) {
+            String[] mappedRoles = getMappedRoleNames(roles, roleMappings);
+
+            for (String role : mappedRoles) {
                if (SEND_NAME.equals(type)) {
                   send.add(role.trim());
                } else if (CONSUME_NAME.equals(type)) {
@@ -770,7 +785,6 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
                }
             }
          }
-
       }
 
       for (String role : allRoles) {
@@ -780,6 +794,23 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
       return securityMatch;
    }
 
+   /**
+    * Translate and expand a set of role names to a set of mapped role names, also includes the original role names
+    * @param roles the original set of role names
+    * @param roleMappings a one-to-many mapping of original role names to mapped role names
+    * @return the final set of mapped role names
+    */
+   private String[] getMappedRoleNames(String[] roles, Map<String, Set<String>> roleMappings) {
+      Set<String> mappedRoles = new HashSet<>();
+      for (String role : roles) {
+         if (roleMappings.containsKey(role)) {
+            mappedRoles.addAll(roleMappings.get(role));
+         }
+         mappedRoles.add(role);
+      }
+      return mappedRoles.toArray(new String[mappedRoles.size()]);
+   }
+
    private Pair<SecuritySettingPlugin, Map<String, String>> parseSecuritySettingPlugins(Node item) {
       final String clazz = item.getAttributes().getNamedItem("class-name").getNodeValue();
       final Map<String, String> settings = new HashMap<>();
@@ -805,6 +836,38 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
    }
 
    /**
+    * Computes the map of internal ActiveMQ role names to sets of external (e.g. LDAP) role names.  For example, given a role
+    * "myrole" with a DN of "cn=myrole,dc=local,dc=com":
+    *      from="cn=myrole,dc=local,dc=com", to="amq,admin,guest"
+    *      from="cn=myOtherRole,dc=local,dc=com", to="amq"
+    * The resulting map will consist of:
+    *      amq => {"cn=myrole,dc=local,dc=com","cn=myOtherRole",dc=local,dc=com"}
+    *      admin => {"cn=myrole,dc=local,dc=com"}
+    *      guest => {"cn=myrole,dc=local,dc=com"}
+    * @param item the role-mapping node
+    * @return the map of local ActiveMQ role names to the set of mapped role names
+    */
+   private Map<String, Set<String>> parseSecurityRoleMapping(Node item) {
+      Map<String, Set<String>> mappedRoleNames = new HashMap<>();
+      String externalRoleName = getAttributeValue(item, ROLE_FROM_ATTR_NAME).trim();
+      Set<String> internalRoleNames = new HashSet<>();
+      Collections.addAll(internalRoleNames, getAttributeValue(item, ROLE_TO_ATTR_NAME).split(","));
+      for (String internalRoleName : internalRoleNames) {
+         internalRoleName = internalRoleName.trim();
+         if (mappedRoleNames.containsKey(internalRoleName)) {
+            mappedRoleNames.get(internalRoleName).add(externalRoleName);
+         } else {
+            Set<String> externalRoleNames = new HashSet<>();
+            externalRoleNames.add(externalRoleName);
+            if ((internalRoleName.length() > 0) && (externalRoleName.length() > 0)) {
+               mappedRoleNames.put(internalRoleName, externalRoleNames);
+            }
+         }
+      }
+      return mappedRoleNames;
+   }
+
+   /**
     * @param node
     * @return
     */

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/24e37993/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 e6eaf8b..1f64930 100644
--- a/artemis-server/src/main/resources/schema/artemis-configuration.xsd
+++ b/artemis-server/src/main/resources/schema/artemis-configuration.xsd
@@ -754,81 +754,102 @@
                   a list of security settings
                </xsd:documentation>
             </xsd:annotation>
+            
             <xsd:complexType>
-               <xsd:choice>
-                  <xsd:element name="security-setting" maxOccurs="unbounded" minOccurs="0">
+               <xsd:sequence>
+                  <xsd:choice>
+                     <xsd:element name="security-setting" maxOccurs="unbounded" minOccurs="0">
+                        <xsd:complexType>
+                           <xsd:annotation>
+                              <xsd:documentation>
+                                 a permission to add to the matched addresses
+                              </xsd:documentation>
+                           </xsd:annotation>
+                           <xsd:sequence>
+                              <xsd:element name="permission" maxOccurs="unbounded" minOccurs="0">
+                                 <xsd:complexType>
+                                    <xsd:attribute name="type" type="xsd:string" use="required">
+                                       <xsd:annotation>
+                                          <xsd:documentation>
+                                             the type of permission
+                                          </xsd:documentation>
+                                       </xsd:annotation>
+                                    </xsd:attribute>
+                                    <xsd:attribute name="roles" type="xsd:string" use="required">
+                                       <xsd:annotation>
+                                          <xsd:documentation>
+                                             a comma-separated list of roles to apply the permission to
+                                          </xsd:documentation>
+                                       </xsd:annotation>
+                                    </xsd:attribute>
+                                 </xsd:complexType>
+                              </xsd:element>
+                           </xsd:sequence>
+                           <xsd:attribute name="match" type="xsd:string" use="required">
+                              <xsd:annotation>
+                                 <xsd:documentation>
+                                    regular expression for matching security roles against addresses
+                                 </xsd:documentation>
+                              </xsd:annotation>
+                           </xsd:attribute>
+                        </xsd:complexType>
+                     </xsd:element>
+                     <xsd:element name="security-setting-plugin" maxOccurs="1" minOccurs="0">
+                        <xsd:complexType>
+                           <xsd:annotation>
+                              <xsd:documentation>
+                                 a plugin
+                              </xsd:documentation>
+                           </xsd:annotation>
+                           <xsd:sequence>
+                              <xsd:element name="setting" maxOccurs="unbounded" minOccurs="0">
+                                 <xsd:complexType>
+                                    <xsd:attribute name="name" type="xsd:string" use="required">
+                                       <xsd:annotation>
+                                          <xsd:documentation>
+                                             the name of the setting
+                                          </xsd:documentation>
+                                       </xsd:annotation>
+                                    </xsd:attribute>
+                                    <xsd:attribute name="value" type="xsd:string" use="required">
+                                       <xsd:annotation>
+                                          <xsd:documentation>
+                                             the value for the setting
+                                          </xsd:documentation>
+                                       </xsd:annotation>
+                                    </xsd:attribute>
+                                 </xsd:complexType>
+                              </xsd:element>
+                           </xsd:sequence>
+                           <xsd:attribute name="class-name" type="xsd:string" use="required">
+                              <xsd:annotation>
+                                 <xsd:documentation>
+                                    the name of the plugin class to instantiate
+                                 </xsd:documentation>
+                              </xsd:annotation>
+                           </xsd:attribute>
+                        </xsd:complexType>
+                     </xsd:element>
+                  </xsd:choice>
+                  <xsd:element name="role-mapping" minOccurs="0" maxOccurs="unbounded">
                      <xsd:complexType>
-                        <xsd:annotation>
-                           <xsd:documentation>
-                              a permission to add to the matched addresses
-                           </xsd:documentation>
-                        </xsd:annotation>
-                        <xsd:sequence>
-                           <xsd:element name="permission" maxOccurs="unbounded" minOccurs="0">
-                              <xsd:complexType>
-                                 <xsd:attribute name="type" type="xsd:string" use="required">
-                                    <xsd:annotation>
-                                       <xsd:documentation>
-                                          the type of permission
-                                       </xsd:documentation>
-                                    </xsd:annotation>
-                                 </xsd:attribute>
-                                 <xsd:attribute name="roles" type="xsd:string" use="required">
-                                    <xsd:annotation>
-                                       <xsd:documentation>
-                                          a comma-separated list of roles to apply the permission to
-                                       </xsd:documentation>
-                                    </xsd:annotation>
-                                 </xsd:attribute>
-                              </xsd:complexType>
-                           </xsd:element>
-                        </xsd:sequence>
-                        <xsd:attribute name="match" type="xsd:string" use="required">
+                        <xsd:attribute name="from" type="xsd:string" use="required">
                            <xsd:annotation>
                               <xsd:documentation>
-                                 regular expression for matching security roles against addresses
+                                 the name of the external role
                               </xsd:documentation>
                            </xsd:annotation>
                         </xsd:attribute>
-                     </xsd:complexType>
-                  </xsd:element>
-                  <xsd:element name="security-setting-plugin" maxOccurs="1" minOccurs="0">
-                     <xsd:complexType>
-                        <xsd:annotation>
-                           <xsd:documentation>
-                              a plugin
-                           </xsd:documentation>
-                        </xsd:annotation>
-                        <xsd:sequence>
-                           <xsd:element name="setting" maxOccurs="unbounded" minOccurs="0">
-                              <xsd:complexType>
-                                 <xsd:attribute name="name" type="xsd:string" use="required">
-                                    <xsd:annotation>
-                                       <xsd:documentation>
-                                          the name of the setting
-                                       </xsd:documentation>
-                                    </xsd:annotation>
-                                 </xsd:attribute>
-                                 <xsd:attribute name="value" type="xsd:string" use="required">
-                                    <xsd:annotation>
-                                       <xsd:documentation>
-                                          the value for the setting
-                                       </xsd:documentation>
-                                    </xsd:annotation>
-                                 </xsd:attribute>
-                              </xsd:complexType>
-                           </xsd:element>
-                        </xsd:sequence>
-                        <xsd:attribute name="class-name" type="xsd:string" use="required">
+                        <xsd:attribute name="to" type="xsd:string" use="required">
                            <xsd:annotation>
                               <xsd:documentation>
-                                 the name of the plugin class to instantiate
+                                 the comma delimited name of the internal role(s)
                               </xsd:documentation>
                            </xsd:annotation>
                         </xsd:attribute>
                      </xsd:complexType>
                   </xsd:element>
-               </xsd:choice>
+               </xsd:sequence>
             </xsd:complexType>
          </xsd:element>
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/24e37993/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 1cebc8c..c87ce34 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
@@ -477,6 +477,90 @@ public class FileConfigurationTest extends ConfigurationImplTest {
    }
 
    @Test
+   public void testSecurityRoleMapping() throws Exception {
+      FileConfiguration fc = new FileConfiguration();
+      FileDeploymentManager deploymentManager = new FileDeploymentManager("securityRoleMappings.xml");
+      deploymentManager.addDeployable(fc);
+      deploymentManager.readConfiguration();
+
+      Map<String, Set<Role>> securityRoles = fc.getSecurityRoles();
+      Set<Role> roles = securityRoles.get("#");
+
+      //N.B. - FileConfigurationParser uses the constructor without createAddress and deleteAddress
+      //cn=mygroup,dc=local,dc=com = amq1
+      Role testRole1 = new Role("cn=mygroup,dc=local,dc=com",false, false, false,
+                               false, true, false, false,
+                               false);
+
+      //myrole1 = amq1 + amq2
+      Role testRole2 = new Role("myrole1",false, false, false,
+                                false, true, true, false,
+                                false);
+
+      //myrole3 = amq3 + amq4
+      Role testRole3 = new Role("myrole3",false, false, true,
+                                true, false, false, false,
+                                false);
+
+      //myrole4 = amq5 + amq!@#$%^&*() + amq6
+      Role testRole4 = new Role("myrole4",true, true, false,
+                                false, false, false, false,
+                                true);
+
+      //myrole5 = amq4 = amq3 + amq4
+      Role testRole5 = new Role("myrole5",false, false, true,
+                                true, false, false, false,
+                                false);
+
+      Role testRole6 = new Role("amq1",false, false, false,
+                                false, true, false, false,
+                                false);
+
+      Role testRole7 = new Role("amq2",false, false, false,
+                                false, false, true, false,
+                                false);
+
+      Role testRole8 = new Role("amq3",false, false, true,
+                                false, false, false, false,
+                                false);
+
+      Role testRole9 = new Role("amq4",false, false, true,
+                                true, false, false, false,
+                                false);
+
+      Role testRole10 = new Role("amq5",false, false, false,
+                                false, false, false, false,
+                                false);
+
+      Role testRole11 = new Role("amq6",false, true, false,
+                                false, false, false, false,
+                                true);
+
+      Role testRole12 = new Role("amq7",false, false, false,
+                                false, false, false, true,
+                                false);
+
+      Role testRole13 = new Role("amq!@#$%^&*()",true, false, false,
+                                false, false, false, false,
+                                false);
+
+      assertEquals(13, roles.size());
+      assertTrue(roles.contains(testRole1));
+      assertTrue(roles.contains(testRole2));
+      assertTrue(roles.contains(testRole3));
+      assertTrue(roles.contains(testRole4));
+      assertTrue(roles.contains(testRole5));
+      assertTrue(roles.contains(testRole6));
+      assertTrue(roles.contains(testRole7));
+      assertTrue(roles.contains(testRole8));
+      assertTrue(roles.contains(testRole9));
+      assertTrue(roles.contains(testRole10));
+      assertTrue(roles.contains(testRole11));
+      assertTrue(roles.contains(testRole12));
+      assertTrue(roles.contains(testRole13));
+   }
+
+   @Test
    public void testContextClassLoaderUsage() throws Exception {
 
       final File customConfiguration = File.createTempFile("hornetq-unittest", ".xml");

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/24e37993/artemis-server/src/test/resources/securityRoleMappings.xml
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/resources/securityRoleMappings.xml b/artemis-server/src/test/resources/securityRoleMappings.xml
new file mode 100644
index 0000000..6994ceb
--- /dev/null
+++ b/artemis-server/src/test/resources/securityRoleMappings.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 ../../../../activemq-server/src/main/resources/schema/artemis-server.xsd">
+   <core xmlns="urn:activemq:core">
+      <security-settings>
+         <security-setting match="#">
+            <permission type="createNonDurableQueue" roles="amq1"/>
+            <permission type="deleteNonDurableQueue" roles="amq2"/>
+            <permission type="createDurableQueue" roles="amq3,amq4"/>
+            <permission type="deleteDurableQueue" roles="amq4"/>
+            <permission type="createAddress" roles="amq5"/>
+            <permission type="deleteAddress" roles="amq5"/>
+            <permission type="consume" roles="amq6"/>
+            <permission type="browse" roles="amq6"/>
+            <permission type="send" roles="amq!@#$%^&amp;*()"/>
+            <!-- we need this otherwise ./artemis data imp wouldn't work -->
+            <permission type="manage" roles="amq7"/>
+         </security-setting>
+         <role-mapping from="cn=mygroup,dc=local,dc=com" to="amq1" />
+         <role-mapping from="myrole1" to="amq1,amq2" />
+         <role-mapping from="myrole2" to="" />
+         <role-mapping from="myrole3" to="amq3" />
+         <role-mapping from="myrole3" to="amq4" />
+         <role-mapping from="myrole4" to="amq5,amq!@#$%^&amp;*(),amq6" />
+         <role-mapping from="myrole5" to="amq4" />
+      </security-settings>
+   </core>
+</configuration>