activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From clebertsuco...@apache.org
Subject [activemq-artemis] branch master updated: ARTEMIS-2574 allow security manager config via XML
Date Thu, 12 Dec 2019 20:48:58 GMT
This is an automated email from the ASF dual-hosted git repository.

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


The following commit(s) were added to refs/heads/master by this push:
     new c064044  ARTEMIS-2574 allow security manager config via XML
     new c2eb037  This closes #2917
c064044 is described below

commit c06404406c0545ab99e9b7cb073feb8ea262b611
Author: Justin Bertram <jbertram@apache.org>
AuthorDate: Tue Dec 10 15:15:21 2019 -0600

    ARTEMIS-2574 allow security manager config via XML
    
    The test-suite has long used the broker's ability to configure the
    security manager. This commit implements this functionality via XML
    configuration.
---
 .../factory/security/SecurityManagerHandler.java   |  42 ++++
 .../artemis/broker/security/security-manager       |   6 +-
 .../org/apache/activemq/cli/test/ArtemisTest.java  |  89 ++++++-
 .../activemq/cli/test/TestSecurityManager.java     |  62 +++++
 .../src/test/scripts/run-examples.sh               |   1 +
 .../src/test/scripts/run-standard-examples.sh      |   1 +
 .../apache/activemq/artemis/dto/PropertyDTO.java   |  33 +++
 .../activemq/artemis/dto/SecurityManagerDTO.java   |  35 +++
 .../org/apache/activemq/artemis/dto/jaxb.index     |   1 +
 .../spi/core/security/ActiveMQSecurityManager.java |  13 +
 docs/user-manual/en/security.md                    |  30 ++-
 docs/user-manual/en/using-server.md                |   8 +-
 examples/features/standard/pom.xml                 |   2 +
 .../features/standard/security-manager/pom.xml     | 137 +++++++++++
 .../features/standard/security-manager/readme.md   |   5 +
 .../jms/example/JAASSecurityManagerWrapper.java    |  72 ++++++
 .../jms/example/SecurityManagerExample.java        | 271 +++++++++++++++++++++
 .../activemq/server0/artemis-roles.properties      |  15 +-
 .../activemq/server0/artemis-users.properties      |  20 ++
 .../main/resources/activemq/server0/bootstrap.xml  |  32 +++
 .../src/main/resources/activemq/server0/broker.xml |  80 ++++++
 .../src/main/resources/jndi.properties             |  22 ++
 22 files changed, 959 insertions(+), 18 deletions(-)

diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/SecurityManagerHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/SecurityManagerHandler.java
new file mode 100644
index 0000000..604d61b
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/security/SecurityManagerHandler.java
@@ -0,0 +1,42 @@
+/*
+ * 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.cli.factory.security;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.activemq.artemis.dto.SecurityManagerDTO;
+import org.apache.activemq.artemis.dto.PropertyDTO;
+import org.apache.activemq.artemis.dto.SecurityDTO;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
+import org.apache.activemq.artemis.utils.ClassloadingUtil;
+
+public class SecurityManagerHandler implements SecurityHandler {
+
+   @Override
+   public ActiveMQSecurityManager createSecurityManager(SecurityDTO security) {
+      SecurityManagerDTO customSecurity = (SecurityManagerDTO) security;
+      String clazz = customSecurity.className;
+      Map<String, String> properties = new HashMap<>();
+      for (PropertyDTO property : customSecurity.properties) {
+         properties.put(property.key, property.value);
+      }
+      return AccessController.doPrivileged((PrivilegedAction<ActiveMQSecurityManager>) () -> (ActiveMQSecurityManager) ClassloadingUtil.newInstanceFromClassLoader(SecurityManagerHandler.class, clazz)).init(properties);
+   }
+}
diff --git a/artemis-dto/src/main/resources/org/apache/activemq/artemis/dto/jaxb.index b/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/security/security-manager
similarity index 92%
copy from artemis-dto/src/main/resources/org/apache/activemq/artemis/dto/jaxb.index
copy to artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/security/security-manager
index 73ff377..128f226 100644
--- a/artemis-dto/src/main/resources/org/apache/activemq/artemis/dto/jaxb.index
+++ b/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/security/security-manager
@@ -14,8 +14,4 @@
 ## See the License for the specific language governing permissions and
 ## limitations under the License.
 ## ---------------------------------------------------------------------------
-BrokerDTO
-SecurityDTO
-JaasSecurityDTO
-ManagementContextDTO
-
+class=org.apache.activemq.artemis.cli.factory.security.SecurityManagerHandler
diff --git a/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java b/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
index b3f8f39..b6c995b 100644
--- a/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
+++ b/artemis-cli/src/test/java/org/apache/activemq/cli/test/ArtemisTest.java
@@ -28,6 +28,10 @@ import javax.json.JsonObject;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -43,6 +47,8 @@ import org.apache.activemq.artemis.api.core.JsonUtil;
 import org.apache.activemq.artemis.api.core.Pair;
 import org.apache.activemq.artemis.api.core.RoutingType;
 import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
+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;
@@ -62,12 +68,13 @@ import org.apache.activemq.artemis.cli.commands.util.SyncCalculation;
 import org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl;
 import org.apache.activemq.artemis.core.config.FileDeploymentManager;
 import org.apache.activemq.artemis.core.config.impl.FileConfiguration;
+import org.apache.activemq.artemis.core.security.CheckType;
 import org.apache.activemq.artemis.core.server.ActiveMQServer;
 import org.apache.activemq.artemis.core.server.JournalType;
 import org.apache.activemq.artemis.core.server.management.ManagementContext;
-import org.apache.activemq.artemis.nativo.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
 import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
+import org.apache.activemq.artemis.nativo.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.utils.DefaultSensitiveStringCodec;
 import org.apache.activemq.artemis.utils.HashProcessor;
 import org.apache.activemq.artemis.utils.PasswordMaskingUtil;
@@ -81,6 +88,8 @@ import org.junit.Before;
 import org.junit.Test;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
 import static org.junit.Assert.assertEquals;
@@ -236,6 +245,84 @@ public class ArtemisTest extends CliTestBase {
    }
 
    @Test
+   public void testSecurityManagerConfiguration() throws Exception {
+      setupAuth();
+      Run.setEmbedded(true);
+      File instance1 = new File(temporaryFolder.getRoot(), "instance1");
+      Artemis.main("create", instance1.getAbsolutePath(), "--silent", "--no-fsync", "--no-autotune", "--no-web", "--no-stomp-acceptor", "--no-amqp-acceptor", "--no-mqtt-acceptor", "--no-hornetq-acceptor");
+      File originalBootstrapFile = new File(new File(instance1, "etc"), "bootstrap.xml");
+      assertTrue(originalBootstrapFile.exists());
+
+      // modify the XML programmatically since we don't support setting this stuff via the CLI
+      Document config = parseXml(originalBootstrapFile);
+      Node broker = config.getChildNodes().item(1);
+      NodeList list = broker.getChildNodes();
+      Node server = null;
+
+      for (int i = 0; i < list.getLength(); i++) {
+         Node node = list.item(i);
+         if ("jaas-security".equals(node.getNodeName())) {
+            // get rid of the default jaas-security config
+            broker.removeChild(node);
+         }
+         if ("server".equals(node.getNodeName())) {
+            server = node;
+         }
+      }
+
+      // add the new security-plugin config
+      Element securityPluginElement = config.createElement("security-manager");
+      securityPluginElement.setAttribute("class-name", TestSecurityManager.class.getName());
+      Element property1 = config.createElement("property");
+      property1.setAttribute("key", "myKey1");
+      property1.setAttribute("value", "myValue1");
+      securityPluginElement.appendChild(property1);
+      Element property2 = config.createElement("property");
+      property2.setAttribute("key", "myKey2");
+      property2.setAttribute("value", "myValue2");
+      securityPluginElement.appendChild(property2);
+      broker.insertBefore(securityPluginElement, server);
+
+      originalBootstrapFile.delete();
+
+      // write the modified config into the bootstrap.xml file
+      TransformerFactory transformerFactory = TransformerFactory.newInstance();
+      Transformer transformer = transformerFactory.newTransformer();
+      DOMSource source = new DOMSource(config);
+      StreamResult streamResult = new StreamResult(originalBootstrapFile);
+      transformer.transform(source, streamResult);
+
+      System.setProperty("artemis.instance", instance1.getAbsolutePath());
+      Object result = Artemis.internalExecute("run");
+      ActiveMQServer activeMQServer = ((Pair<ManagementContext, ActiveMQServer>)result).getB();
+
+      // trigger security
+      ServerLocator locator = ActiveMQClient.createServerLocator("tcp://127.0.0.1:61616");
+      ClientSessionFactory sessionFactory = locator.createSessionFactory();
+      ClientSession session = sessionFactory.createSession("myUser", "myPass", false, true, true, false, 0);
+      ClientProducer producer = session.createProducer("foo");
+      producer.send(session.createMessage(true));
+
+      // verify results
+      assertTrue(activeMQServer.getSecurityManager() instanceof TestSecurityManager);
+      TestSecurityManager securityPlugin = (TestSecurityManager) activeMQServer.getSecurityManager();
+      assertTrue(securityPlugin.properties.containsKey("myKey1"));
+      assertEquals("myValue1", securityPlugin.properties.get("myKey1"));
+      assertTrue(securityPlugin.properties.containsKey("myKey2"));
+      assertEquals("myValue2", securityPlugin.properties.get("myKey2"));
+      assertTrue(securityPlugin.validateUser);
+      assertEquals("myUser", securityPlugin.validateUserName);
+      assertEquals("myPass", securityPlugin.validateUserPass);
+      assertTrue(securityPlugin.validateUserAndRole);
+      assertEquals("myUser", securityPlugin.validateUserAndRoleName);
+      assertEquals("myPass", securityPlugin.validateUserAndRolePass);
+      assertEquals(CheckType.SEND, securityPlugin.checkType);
+
+      activeMQServer.stop();
+      stopServer();
+   }
+
+   @Test
    public void testStopManagementContext() throws Exception {
       Run.setEmbedded(true);
       File instance1 = new File(temporaryFolder.getRoot(), "instance_user");
diff --git a/artemis-cli/src/test/java/org/apache/activemq/cli/test/TestSecurityManager.java b/artemis-cli/src/test/java/org/apache/activemq/cli/test/TestSecurityManager.java
new file mode 100644
index 0000000..94dc6f0
--- /dev/null
+++ b/artemis-cli/src/test/java/org/apache/activemq/cli/test/TestSecurityManager.java
@@ -0,0 +1,62 @@
+/**
+ * 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.cli.test;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.activemq.artemis.core.security.CheckType;
+import org.apache.activemq.artemis.core.security.Role;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
+
+/**
+ * This is a simple *test* security manager used to verify configuration via bootstrap.xml.
+ */
+public class TestSecurityManager implements ActiveMQSecurityManager {
+   public Map<String, String> properties;
+   public boolean validateUser = false;
+   public String validateUserName;
+   public String validateUserPass;
+   public boolean validateUserAndRole = false;
+   public String validateUserAndRoleName;
+   public String validateUserAndRolePass;
+   public CheckType checkType;
+
+   @Override
+   public boolean validateUser(String user, String password) {
+      this.validateUser = true;
+      this.validateUserName = user;
+      this.validateUserPass = password;
+      return true;
+   }
+
+   @Override
+   public boolean validateUserAndRole(String user, String password, Set<Role> roles, CheckType checkType) {
+      this.validateUserAndRole = true;
+      this.validateUserAndRoleName = user;
+      this.validateUserAndRolePass = password;
+      this.checkType = checkType;
+      return true;
+   }
+
+   @Override
+   public ActiveMQSecurityManager init(Map<String, String> properties) {
+      this.properties = properties;
+      return this;
+   }
+}
diff --git a/artemis-distribution/src/test/scripts/run-examples.sh b/artemis-distribution/src/test/scripts/run-examples.sh
index bf643f6..67fbb8c 100755
--- a/artemis-distribution/src/test/scripts/run-examples.sh
+++ b/artemis-distribution/src/test/scripts/run-examples.sh
@@ -81,6 +81,7 @@ cd rest; mvn verify; cd ..
 cd scheduled-message; mvn verify; cd ..
 cd security; mvn verify; cd ..
 cd security-ldap; mvn verify; cd ..
+cd security-manager; mvn verify; cd ..
 cd send-acknowledgements; mvn verify; cd ..
 cd shared-consumer; mvn verify; cd ..
 cd slow-consumer; mvn verify; cd ..
diff --git a/artemis-distribution/src/test/scripts/run-standard-examples.sh b/artemis-distribution/src/test/scripts/run-standard-examples.sh
index fbbaff5..85cea6f 100755
--- a/artemis-distribution/src/test/scripts/run-standard-examples.sh
+++ b/artemis-distribution/src/test/scripts/run-standard-examples.sh
@@ -80,6 +80,7 @@ cd rest; mvn verify; cd ..
 cd scheduled-message; mvn verify; cd ..
 cd security; mvn verify; cd ..
 cd security-ldap; mvn verify; cd ..
+cd security-manager; mvn verify; cd ..
 cd send-acknowledgements; mvn verify; cd ..
 cd shared-consumer; mvn verify; cd ..
 cd slow-consumer; mvn verify; cd ..
diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/PropertyDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/PropertyDTO.java
new file mode 100644
index 0000000..c1015a8
--- /dev/null
+++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/PropertyDTO.java
@@ -0,0 +1,33 @@
+/*
+ * 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.dto;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "property")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class PropertyDTO {
+
+   @XmlAttribute
+   public String key;
+
+   @XmlAttribute
+   public String value;
+}
diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/SecurityManagerDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/SecurityManagerDTO.java
new file mode 100644
index 0000000..1fd3d6d
--- /dev/null
+++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/SecurityManagerDTO.java
@@ -0,0 +1,35 @@
+/*
+ * 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.dto;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.List;
+
+@XmlRootElement(name = "security-manager")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class SecurityManagerDTO extends SecurityDTO {
+
+   @XmlAttribute(name = "class-name", required = true)
+   public String className;
+
+   @XmlElementRef
+   public List<PropertyDTO> properties;
+}
diff --git a/artemis-dto/src/main/resources/org/apache/activemq/artemis/dto/jaxb.index b/artemis-dto/src/main/resources/org/apache/activemq/artemis/dto/jaxb.index
index 73ff377..4840267 100644
--- a/artemis-dto/src/main/resources/org/apache/activemq/artemis/dto/jaxb.index
+++ b/artemis-dto/src/main/resources/org/apache/activemq/artemis/dto/jaxb.index
@@ -17,5 +17,6 @@
 BrokerDTO
 SecurityDTO
 JaasSecurityDTO
+SecurityManagerDTO
 ManagementContextDTO
 
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQSecurityManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQSecurityManager.java
index 3576c86..afde137 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQSecurityManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQSecurityManager.java
@@ -16,6 +16,7 @@
  */
 package org.apache.activemq.artemis.spi.core.security;
 
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.activemq.artemis.core.security.CheckType;
@@ -50,4 +51,16 @@ public interface ActiveMQSecurityManager {
     * @return true if the user is valid and they have the correct roles
     */
    boolean validateUserAndRole(String user, String password, Set<Role> roles, CheckType checkType);
+
+   /**
+    * Initialize the manager with the given configuration properties. This method is called by the broker when the
+    * file-based configuration is read. If you're creating/configuring the plugin programmatically then the
+    * recommended approach is to simply use the manager's getters/setters rather than this method.
+    *
+    * @param properties name/value pairs used to configure the ActiveMQSecurityManager instance
+    * @return {@code this} instance
+    */
+   default ActiveMQSecurityManager init(Map<String, String> properties) {
+      return this;
+   }
 }
diff --git a/docs/user-manual/en/security.md b/docs/user-manual/en/security.md
index 140fdc8..61d395d 100644
--- a/docs/user-manual/en/security.md
+++ b/docs/user-manual/en/security.md
@@ -1,8 +1,10 @@
 # Security
 
 This chapter describes how security works with Apache ActiveMQ Artemis and how
-you can configure it. To disable security completely simply set the
-`security-enabled` property to false in the `broker.xml` file.
+you can configure it.
+
+To disable security completely simply set the `security-enabled` property to
+`false` in the `broker.xml` file.
 
 For performance reasons security is cached and invalidated every so long. To
 change this period set the property `security-invalidation-interval`, which is
@@ -1202,3 +1204,27 @@ The param-value for each list is a comma separated string value representing the
 
 For details about masking passwords in broker.xml please see the [Masking
 Passwords](masking-passwords.md) chapter.
+
+## Custom Security Manager
+
+The underpinnings of the broker's security implementation can be changed if so
+desired. The broker uses a component called a "security manager" to implement
+the actual authentication and authorization checks. By default, the broker uses
+`org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager` to
+provide JAAS integration, but users can provide their own implementation of
+`org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager3` and
+configure it in `bootstrap.xml` using the `security-manager` element, e.g.:
+
+```xml
+<broker xmlns="http://activemq.org/schema">
+
+   <security-manager class-name="com.foo.MySecurityManager">
+      <property key="myKey1" value="myValue1"/>
+      <property key="myKey2" value="myValue2"/>
+   </security-manager>
+
+   ...
+</broker>
+```
+
+The `security-manager` example demonstrates how to do this is more detail.
diff --git a/docs/user-manual/en/using-server.md b/docs/user-manual/en/using-server.md
index 1e7b743..845c66c 100644
--- a/docs/user-manual/en/using-server.md
+++ b/docs/user-manual/en/using-server.md
@@ -438,8 +438,12 @@ The bootstrap file is very simple. Let's take a look at an example:
   `configuration` attribute. This is the main broker POJO necessary to do all
    the real messaging work.
 
-- `jaas-security` - Configures security for the server. The `domain` attribute
-   refers to the relevant login module entry in `login.config`.
+- `jaas-security` - Configures JAAS-based security for the server. The
+  `domain` attribute refers to the relevant login module entry in
+  `login.config`. If different behavior is needed then a custom security
+  manager can be configured by replacing `jaas-security` with
+  `security-manager`. See the "Custom Security Manager" section in the
+  [security chapter](security.md) for more details.
 
 - `web` - Configures an embedded Jetty instance to serve web applications like
   the admin console.
diff --git a/examples/features/standard/pom.xml b/examples/features/standard/pom.xml
index 5f21f7e..1caa937 100644
--- a/examples/features/standard/pom.xml
+++ b/examples/features/standard/pom.xml
@@ -91,6 +91,7 @@ under the License.
             <module>scheduled-message</module>
             <module>security</module>
             <module>security-ldap</module>
+            <module>security-manager</module>
             <module>send-acknowledgements</module>
             <module>shared-consumer</module>
             <module>slow-consumer</module>
@@ -164,6 +165,7 @@ under the License.
             <module>scheduled-message</module>
             <module>security</module>
             <module>security-ldap</module>
+            <module>security-manager</module>
             <module>send-acknowledgements</module>
             <module>shared-consumer</module>
             <module>slow-consumer</module>
diff --git a/examples/features/standard/security-manager/pom.xml b/examples/features/standard/security-manager/pom.xml
new file mode 100644
index 0000000..2ceed50
--- /dev/null
+++ b/examples/features/standard/security-manager/pom.xml
@@ -0,0 +1,137 @@
+<?xml version='1.0'?>
+<!--
+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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+   <modelVersion>4.0.0</modelVersion>
+
+   <parent>
+      <groupId>org.apache.activemq.examples.broker</groupId>
+      <artifactId>jms-examples</artifactId>
+      <version>2.11.0-SNAPSHOT</version>
+   </parent>
+
+   <artifactId>security-manager</artifactId>
+   <packaging>jar</packaging>
+   <name>ActiveMQ Artemis JMS Security Manager Example</name>
+
+   <properties>
+      <activemq.basedir>${project.basedir}/../../../..</activemq.basedir>
+   </properties>
+
+   <dependencies>
+      <dependency>
+         <groupId>org.apache.activemq</groupId>
+         <artifactId>artemis-jms-client-all</artifactId>
+         <version>${project.version}</version>
+      </dependency>
+      <dependency>
+         <groupId>org.apache.activemq</groupId>
+         <artifactId>artemis-server</artifactId>
+         <version>${project.version}</version>
+         <scope>compile</scope>
+      </dependency>
+   </dependencies>
+
+   <build>
+      <plugins>
+         <plugin>
+            <groupId>org.apache.activemq</groupId>
+            <artifactId>artemis-maven-plugin</artifactId>
+            <executions>
+               <execution>
+                  <id>create</id>
+                  <goals>
+                     <goal>create</goal>
+                  </goals>
+                  <configuration>
+                     <libList>
+                        <!-- For the security manager -->
+                        <arg>org.apache.activemq.examples.broker:security-manager:${project.version}</arg>
+                     </libList>
+                     <ignore>${noServer}</ignore>
+                     <allowAnonymous>false</allowAnonymous>
+                  </configuration>
+               </execution>
+               <execution>
+                  <id>start</id>
+                  <goals>
+                     <goal>cli</goal>
+                  </goals>
+                  <configuration>
+                     <ignore>${noServer}</ignore>
+                     <spawn>true</spawn>
+                     <testURI>tcp://localhost:61616</testURI>
+                     <testUser>bill</testUser>
+                     <testPassword>activemq</testPassword>
+                     <args>
+                        <param>run</param>
+                     </args>
+                  </configuration>
+               </execution>
+               <execution>
+                  <id>runClient</id>
+                  <goals>
+                     <goal>runClient</goal>
+                  </goals>
+                  <configuration>
+                     <clientClass>org.apache.activemq.artemis.jms.example.SecurityManagerExample</clientClass>
+                  </configuration>
+               </execution>
+               <execution>
+                  <id>stop</id>
+                  <goals>
+                     <goal>cli</goal>
+                  </goals>
+                  <configuration>
+                     <ignore>${noServer}</ignore>
+                     <args>
+                        <param>stop</param>
+                     </args>
+                  </configuration>
+               </execution>
+            </executions>
+            <dependencies>
+               <dependency>
+                  <groupId>org.apache.activemq.examples.broker</groupId>
+                  <artifactId>security-manager</artifactId>
+                  <version>${project.version}</version>
+               </dependency>
+            </dependencies>
+         </plugin>
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-clean-plugin</artifactId>
+         </plugin>
+      </plugins>
+   </build>
+   <profiles>
+      <profile>
+         <id>release</id>
+         <build>
+            <plugins>
+               <plugin>
+                  <groupId>com.vladsch.flexmark</groupId>
+                  <artifactId>markdown-page-generator-plugin</artifactId>
+               </plugin>
+            </plugins>
+         </build>
+      </profile>
+   </profiles>
+</project>
\ No newline at end of file
diff --git a/examples/features/standard/security-manager/readme.md b/examples/features/standard/security-manager/readme.md
new file mode 100644
index 0000000..32335a4
--- /dev/null
+++ b/examples/features/standard/security-manager/readme.md
@@ -0,0 +1,5 @@
+# JMS Security Manager Example
+
+To run the example, simply type **mvn verify** from this directory, or **mvn -PnoServer verify** if you want to start and create the broker manually.
+
+This example is based on the "security" example and demonstrates how to implement a custom security manager. The custom security manager in this example simply logs details for authentication and authorization and then passes everything through to an instance of `org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager` (i.e. the default security manager).
\ No newline at end of file
diff --git a/examples/features/standard/security-manager/src/main/java/org/apache/activemq/artemis/jms/example/JAASSecurityManagerWrapper.java b/examples/features/standard/security-manager/src/main/java/org/apache/activemq/artemis/jms/example/JAASSecurityManagerWrapper.java
new file mode 100644
index 0000000..c278217
--- /dev/null
+++ b/examples/features/standard/security-manager/src/main/java/org/apache/activemq/artemis/jms/example/JAASSecurityManagerWrapper.java
@@ -0,0 +1,72 @@
+/**
+ * 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.jms.example;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.activemq.artemis.core.security.CheckType;
+import org.apache.activemq.artemis.core.security.Role;
+import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager3;
+
+public class JAASSecurityManagerWrapper implements ActiveMQSecurityManager3 {
+   ActiveMQJAASSecurityManager activeMQJAASSecurityManager;
+
+   @Override
+   public String validateUser(String user, String password, RemotingConnection remotingConnection) {
+      System.out.println("validateUser(" + user + ", " + password + ", " + remotingConnection.getRemoteAddress() + ")");
+      return activeMQJAASSecurityManager.validateUser(user, password, remotingConnection);
+   }
+
+
+   @Override
+   public String validateUserAndRole(String user,
+                              String password,
+                              Set<Role> roles,
+                              CheckType checkType,
+                              String address,
+                              RemotingConnection remotingConnection) {
+      System.out.println("validateUserAndRole(" + user + ", " + password + ", " + roles + ", " + checkType + ", " + address + ", " + remotingConnection.getRemoteAddress() + ")");
+      return activeMQJAASSecurityManager.validateUserAndRole(user, password, roles, checkType, address, remotingConnection);
+   }
+
+   @Override
+   public String getDomain() {
+      return activeMQJAASSecurityManager.getDomain();
+   }
+
+   @Override
+   public boolean validateUser(String user, String password) {
+      return activeMQJAASSecurityManager.validateUser(user, password);
+   }
+
+   @Override
+   public boolean validateUserAndRole(String user, String password, Set<Role> roles, CheckType checkType) {
+      return activeMQJAASSecurityManager.validateUserAndRole(user, password, roles, checkType);
+   }
+
+   @Override
+   public ActiveMQSecurityManager init(Map<String, String> properties) {
+      activeMQJAASSecurityManager = new ActiveMQJAASSecurityManager(properties.get("domain"));
+      return this;
+   }
+
+}
diff --git a/examples/features/standard/security-manager/src/main/java/org/apache/activemq/artemis/jms/example/SecurityManagerExample.java b/examples/features/standard/security-manager/src/main/java/org/apache/activemq/artemis/jms/example/SecurityManagerExample.java
new file mode 100644
index 0000000..7dbd369
--- /dev/null
+++ b/examples/features/standard/security-manager/src/main/java/org/apache/activemq/artemis/jms/example/SecurityManagerExample.java
@@ -0,0 +1,271 @@
+/*
+ * 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.jms.example;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+import javax.jms.JMSSecurityException;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import javax.naming.InitialContext;
+
+public class SecurityManagerExample {
+
+   public static void main(final String[] args) throws Exception {
+      boolean result = true;
+      Connection failConnection = null;
+      Connection billConnection = null;
+      Connection andrewConnection = null;
+      Connection frankConnection = null;
+      Connection samConnection = null;
+
+      InitialContext initialContext = null;
+      try {
+         // /Step 1. Create an initial context to perform the JNDI lookup.
+         initialContext = new InitialContext();
+
+         // Step 2. perform lookup on the topics
+         Topic genericTopic = (Topic) initialContext.lookup("topic/genericTopic");
+         Topic europeTopic = (Topic) initialContext.lookup("topic/europeTopic");
+         Topic usTopic = (Topic) initialContext.lookup("topic/usTopic");
+
+         // Step 3. perform a lookup on the Connection Factory
+         ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory");
+
+         // Step 4. Try to create a JMS Connection without user/password. It will fail.
+         try {
+            failConnection = cf.createConnection();
+            result = false;
+         } catch (JMSSecurityException e) {
+            System.out.println("Default user cannot get a connection. Details: " + e.getMessage());
+         }
+
+         // Step 5. bill tries to make a connection using wrong password
+         try {
+            billConnection = createConnection("bill", "activemq1", cf);
+            result = false;
+         } catch (JMSException e) {
+            System.out.println("User bill failed to connect. Details: " + e.getMessage());
+         }
+
+         // Step 6. bill makes a good connection.
+         billConnection = createConnection("bill", "activemq", cf);
+         billConnection.start();
+
+         // Step 7. andrew makes a good connection.
+         andrewConnection = createConnection("andrew", "activemq1", cf);
+         andrewConnection.start();
+
+         // Step 8. frank makes a good connection.
+         frankConnection = createConnection("frank", "activemq2", cf);
+         frankConnection.start();
+
+         // Step 9. sam makes a good connection.
+         samConnection = createConnection("sam", "activemq3", cf);
+         samConnection.start();
+
+         // Step 10. Check every user can publish/subscribe genericTopics.
+         System.out.println("------------------------Checking permissions on " + genericTopic + "----------------");
+         checkUserSendAndReceive(genericTopic, billConnection, "bill");
+         checkUserSendAndReceive(genericTopic, andrewConnection, "andrew");
+         checkUserSendAndReceive(genericTopic, frankConnection, "frank");
+         checkUserSendAndReceive(genericTopic, samConnection, "sam");
+         System.out.println("-------------------------------------------------------------------------------------");
+
+         System.out.println("------------------------Checking permissions on " + europeTopic + "----------------");
+
+         // Step 11. Check permissions on news.europe.europeTopic for bill: can't send and can't receive
+         checkUserNoSendNoReceive(europeTopic, billConnection, "bill");
+
+         // Step 12. Check permissions on news.europe.europeTopic for andrew: can send but can't receive
+         checkUserSendNoReceive(europeTopic, andrewConnection, "andrew", frankConnection);
+
+         // Step 13. Check permissions on news.europe.europeTopic for frank: can't send but can receive
+         checkUserReceiveNoSend(europeTopic, frankConnection, "frank", andrewConnection);
+
+         // Step 14. Check permissions on news.europe.europeTopic for sam: can't send but can receive
+         checkUserReceiveNoSend(europeTopic, samConnection, "sam", andrewConnection);
+         System.out.println("-------------------------------------------------------------------------------------");
+
+         System.out.println("------------------------Checking permissions on " + usTopic + "----------------");
+
+         // Step 15. Check permissions on news.us.usTopic for bill: can't send and can't receive
+         checkUserNoSendNoReceive(usTopic, billConnection, "bill");
+
+         // Step 16. Check permissions on news.us.usTopic for andrew: can't send and can't receive
+         checkUserNoSendNoReceive(usTopic, andrewConnection, "andrew");
+
+         // Step 17. Check permissions on news.us.usTopic for frank: can both send and receive
+         checkUserSendAndReceive(usTopic, frankConnection, "frank");
+
+         // Step 18. Check permissions on news.us.usTopic for sam: can't send but can receive
+         checkUserReceiveNoSend(usTopic, samConnection, "sam", frankConnection);
+         System.out.println("-------------------------------------------------------------------------------------");
+      } finally {
+         // Step 19. Be sure to close our JMS resources!
+         if (failConnection != null) {
+            failConnection.close();
+         }
+         if (billConnection != null) {
+            billConnection.close();
+         }
+         if (andrewConnection != null) {
+            andrewConnection.close();
+         }
+         if (frankConnection != null) {
+            frankConnection.close();
+         }
+         if (samConnection != null) {
+            samConnection.close();
+         }
+
+         // Also the initialContext
+         if (initialContext != null) {
+            initialContext.close();
+         }
+      }
+   }
+
+   // Check the user can receive message but cannot send message.
+   private static void checkUserReceiveNoSend(final Topic topic,
+                                              final Connection connection,
+                                              final String user,
+                                              final Connection sendingConn) throws JMSException {
+      Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer producer = session.createProducer(topic);
+      MessageConsumer consumer = session.createConsumer(topic);
+      TextMessage msg = session.createTextMessage("hello-world-1");
+
+      try {
+         producer.send(msg);
+         throw new IllegalStateException("Security setting is broken! User " + user +
+                                            " can send message [" +
+                                            msg.getText() +
+                                            "] to topic " +
+                                            topic);
+      } catch (JMSException e) {
+         System.out.println("User " + user + " cannot send message [" + msg.getText() + "] to topic: " + topic);
+      }
+
+      // Now send a good message
+      Session session1 = sendingConn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      producer = session1.createProducer(topic);
+      producer.send(msg);
+
+      TextMessage receivedMsg = (TextMessage) consumer.receive(2000);
+
+      if (receivedMsg != null) {
+         System.out.println("User " + user + " can receive message [" + receivedMsg.getText() + "] from topic " + topic);
+      } else {
+         throw new IllegalStateException("Security setting is broken! User " + user + " cannot receive message from topic " + topic);
+      }
+
+      session1.close();
+      session.close();
+   }
+
+   // Check the user can send message but cannot receive message
+   private static void checkUserSendNoReceive(final Topic topic,
+                                              final Connection connection,
+                                              final String user,
+                                              final Connection receivingConn) throws JMSException {
+      Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer producer = session.createProducer(topic);
+      try {
+         session.createConsumer(topic);
+      } catch (JMSException e) {
+         System.out.println("User " + user + " cannot receive any message from topic " + topic);
+      }
+
+      Session session1 = receivingConn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageConsumer goodConsumer = session1.createConsumer(topic);
+
+      TextMessage msg = session.createTextMessage("hello-world-2");
+      producer.send(msg);
+
+      TextMessage receivedMsg = (TextMessage) goodConsumer.receive(2000);
+      if (receivedMsg != null) {
+         System.out.println("User " + user + " can send message [" + receivedMsg.getText() + "] to topic " + topic);
+      } else {
+         throw new IllegalStateException("Security setting is broken! User " + user +
+                                            " cannot send message [" +
+                                            msg.getText() +
+                                            "] to topic " +
+                                            topic);
+      }
+
+      session.close();
+      session1.close();
+   }
+
+   // Check the user has neither send nor receive permission on topic
+   private static void checkUserNoSendNoReceive(final Topic topic,
+                                                final Connection connection,
+                                                final String user) throws JMSException {
+      Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer producer = session.createProducer(topic);
+
+      try {
+         session.createConsumer(topic);
+      } catch (JMSException e) {
+         System.out.println("User " + user + " cannot create consumer on topic " + topic);
+      }
+
+      TextMessage msg = session.createTextMessage("hello-world-3");
+      try {
+         producer.send(msg);
+         throw new IllegalStateException("Security setting is broken! User " + user +
+                                            " can send message [" +
+                                            msg.getText() +
+                                            "] to topic " +
+                                            topic);
+      } catch (JMSException e) {
+         System.out.println("User " + user + " cannot send message [" + msg.getText() + "] to topic: " + topic);
+      }
+
+      session.close();
+   }
+
+   // Check the user connection has both send and receive permissions on the topic
+   private static void checkUserSendAndReceive(final Topic topic,
+                                               final Connection connection,
+                                               final String user) throws JMSException {
+      Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      TextMessage msg = session.createTextMessage("hello-world-4");
+      MessageProducer producer = session.createProducer(topic);
+      MessageConsumer consumer = session.createConsumer(topic);
+      producer.send(msg);
+      TextMessage receivedMsg = (TextMessage) consumer.receive(5000);
+      if (receivedMsg != null) {
+         System.out.println("User " + user + " can send message: [" + msg.getText() + "] to topic: " + topic);
+         System.out.println("User " + user + " can receive message: [" + msg.getText() + "] from topic: " + topic);
+      } else {
+         throw new IllegalStateException("Error! User " + user + " cannot receive the message! ");
+      }
+      session.close();
+   }
+
+   private static Connection createConnection(final String username,
+                                              final String password,
+                                              final ConnectionFactory cf) throws JMSException {
+      return cf.createConnection(username, password);
+   }
+}
diff --git a/artemis-dto/src/main/resources/org/apache/activemq/artemis/dto/jaxb.index b/examples/features/standard/security-manager/src/main/resources/activemq/server0/artemis-roles.properties
similarity index 75%
copy from artemis-dto/src/main/resources/org/apache/activemq/artemis/dto/jaxb.index
copy to examples/features/standard/security-manager/src/main/resources/activemq/server0/artemis-roles.properties
index 73ff377..71e672d 100644
--- a/artemis-dto/src/main/resources/org/apache/activemq/artemis/dto/jaxb.index
+++ b/examples/features/standard/security-manager/src/main/resources/activemq/server0/artemis-roles.properties
@@ -1,12 +1,12 @@
 ## ---------------------------------------------------------------------------
 ## Licensed to the Apache Software Foundation (ASF) under one or more
-## contributor license agreements. See the NOTICE file distributed with
+## 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
+## the License.  You may obtain a copy of the License at
 ##
-##     http://www.apache.org/licenses/LICENSE-2.0
+## 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,
@@ -14,8 +14,7 @@
 ## See the License for the specific language governing permissions and
 ## limitations under the License.
 ## ---------------------------------------------------------------------------
-BrokerDTO
-SecurityDTO
-JaasSecurityDTO
-ManagementContextDTO
-
+user=bill,andrew,frank,sam
+europe-user=andrew
+news-user=frank,sam
+us-user=frank
\ No newline at end of file
diff --git a/examples/features/standard/security-manager/src/main/resources/activemq/server0/artemis-users.properties b/examples/features/standard/security-manager/src/main/resources/activemq/server0/artemis-users.properties
new file mode 100644
index 0000000..9a4c336
--- /dev/null
+++ b/examples/features/standard/security-manager/src/main/resources/activemq/server0/artemis-users.properties
@@ -0,0 +1,20 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+bill = ENC(1024:020FEC8DB7EBBCB987FD25F1188EA71FA13FD4E0BF504963891EDC97E1ED1285:3E53D34A96F9995612C7C585CA04BA63CF5F531C92510E882960F848BFC3982AF47FCD40AB888F9AC10648CCEBA1DD52C0F0A312B2C90225D9A46DDC50198B3C)
+andrew = ENC(1024:3E09F4D16A6970F3C40E24784AFE64AFD66349174AB20B2609109646A8F0561F:F22063143058EBCF47A0ACA1C29DBCB82C4AF15E510F5C801B47928AEA1836D1480BFD0DFD0320BA567D1A32C98859C02350AE271DC530F29D7E16E910E251AD)
+frank = ENC(1024:49292EEC8AA19AB5390A0F0D67AA5A3978DE1AF0F561B641A1CE90B3C9637AAD:22A8F9A4B144B9CC173F3B1D5A2B09FE57642234534C2EB3A805DB7D5F7FEA398B58EB9380B8EA69B916B5CFA23BC7573E09A87A20C0DF1A35A1134270260BE4)
+sam = ENC(1024:39832F10D9734D7E6EECE16BCEAA5E2917D384B4CE482A2A4B3D3E7A550B0A5C:CCA47914C6DD64AE6B69FE977BB445CBCDEA50D458E7F42AA341FA84A11C302E2EAB072E57B41A636589C89246911A6A49424CBA4B629F4846826183E9AD9DA1)
\ No newline at end of file
diff --git a/examples/features/standard/security-manager/src/main/resources/activemq/server0/bootstrap.xml b/examples/features/standard/security-manager/src/main/resources/activemq/server0/bootstrap.xml
new file mode 100644
index 0000000..2e44003
--- /dev/null
+++ b/examples/features/standard/security-manager/src/main/resources/activemq/server0/bootstrap.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ 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.
+  -->
+
+<broker xmlns="http://activemq.org/schema">
+
+   <security-manager class-name="org.apache.activemq.artemis.jms.example.JAASSecurityManagerWrapper">
+      <property key="domain" value="activemq"/>
+   </security-manager>
+
+   <!-- artemis.URI.instance is parsed from artemis.instance by the CLI startup.
+        This is to avoid situations where you could have spaces or special characters on this URI -->
+   <server configuration="file:/home/jbertram/jboss/src/activemq-artemis/examples/features/standard/security-manager/target/server0/etc//broker.xml"/>
+
+
+
+</broker>
+
diff --git a/examples/features/standard/security-manager/src/main/resources/activemq/server0/broker.xml b/examples/features/standard/security-manager/src/main/resources/activemq/server0/broker.xml
new file mode 100644
index 0000000..6c2c505
--- /dev/null
+++ b/examples/features/standard/security-manager/src/main/resources/activemq/server0/broker.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+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 /schema/artemis-configuration.xsd">
+   <core xmlns="urn:activemq:core">
+
+      <bindings-directory>./data/messaging/bindings</bindings-directory>
+
+      <journal-directory>./data/messaging/journal</journal-directory>
+
+      <large-messages-directory>./data/messaging/largemessages</large-messages-directory>
+
+      <paging-directory>./data/messaging/paging</paging-directory>
+
+      <!-- Acceptors -->
+      <acceptors>
+         <acceptor name="netty-acceptor">tcp://localhost:61616</acceptor>
+      </acceptors>
+
+      <!-- Other config -->
+
+      <security-settings>
+         <!-- any user can have full control of generic topics -->
+         <security-setting match="#">
+            <permission roles="user" type="createDurableQueue"/>
+            <permission roles="user" type="deleteDurableQueue"/>
+            <permission roles="user" type="createNonDurableQueue"/>
+            <permission roles="user" type="deleteNonDurableQueue"/>
+            <permission roles="user" type="send"/>
+            <permission roles="user" type="consume"/>
+         </security-setting>
+
+         <security-setting match="news.europe.#">
+            <permission roles="user" type="createDurableQueue"/>
+            <permission roles="user" type="deleteDurableQueue"/>
+            <permission roles="user" type="createNonDurableQueue"/>
+            <permission roles="user" type="deleteNonDurableQueue"/>
+            <permission roles="europe-user" type="send"/>
+            <permission roles="news-user" type="consume"/>
+         </security-setting>
+
+         <security-setting match="news.us.#">
+            <permission roles="user" type="createDurableQueue"/>
+            <permission roles="user" type="deleteDurableQueue"/>
+            <permission roles="user" type="createNonDurableQueue"/>
+            <permission roles="user" type="deleteNonDurableQueue"/>
+            <permission roles="us-user" type="send"/>
+            <permission roles="news-user" type="consume"/>
+         </security-setting>
+      </security-settings>
+
+      <addresses>
+         <address name="genericTopic">
+            <multicast/>
+         </address>
+         <address name="news.europe.europeTopic">
+            <multicast/>
+         </address>
+         <address name="news.us.usTopic">
+            <multicast/>
+         </address>
+      </addresses>
+   </core>
+</configuration>
diff --git a/examples/features/standard/security-manager/src/main/resources/jndi.properties b/examples/features/standard/security-manager/src/main/resources/jndi.properties
new file mode 100644
index 0000000..0a3b640
--- /dev/null
+++ b/examples/features/standard/security-manager/src/main/resources/jndi.properties
@@ -0,0 +1,22 @@
+# 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.
+
+java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
+connectionFactory.ConnectionFactory=tcp://localhost:61616
+topic.topic/genericTopic=genericTopic
+topic.topic/europeTopic=news.europe.europeTopic
+topic.topic/usTopic=news.us.usTopic


Mime
View raw message