activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From clebertsuco...@apache.org
Subject [2/3] activemq-artemis git commit: ARTEMIS-1463 - add role based authentication to the JMX objects
Date Mon, 16 Oct 2017 14:43:22 GMT
ARTEMIS-1463 - add role based authentication to the JMX objects

This is done by creating a guard and using JAAS to check for access to mbean objects and their methods.

NB this also implements https://issues.apache.org/jira/browse/ARTEMIS-534

https://issues.apache.org/jira/browse/ARTEMIS-1463


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

Branch: refs/heads/master
Commit: 62a2b14dd0497b9b6833e0e3c15c2725ca3bf717
Parents: d0f3f67
Author: Andy Taylor <andy.tayls67@gmail.com>
Authored: Thu Oct 12 13:53:19 2017 +0100
Committer: Andy Taylor <andy.tayls67@gmail.com>
Committed: Mon Oct 16 15:39:38 2017 +0100

----------------------------------------------------------------------
 .../artemis/cli/commands/Configurable.java      |  17 ++
 .../activemq/artemis/cli/commands/Create.java   |   2 +
 .../activemq/artemis/cli/commands/Run.java      |  32 ++-
 .../artemis/cli/factory/jmx/JmxAclHandler.java  |  25 ++
 .../cli/factory/jmx/ManagementFactory.java      | 134 +++++++++
 .../cli/factory/jmx/XmlJmxAclHandler.java       |  36 +++
 .../org/apache/activemq/artemis/broker/jmx/xml  |  17 ++
 .../artemis/cli/commands/etc/management.xml     |  49 ++++
 .../activemq/cli/test/StreamClassPathTest.java  |   1 +
 .../apache/activemq/artemis/dto/AccessDTO.java  |  34 +++
 .../activemq/artemis/dto/AuthorisationDTO.java  |  49 ++++
 .../activemq/artemis/dto/DefaultAccessDTO.java  |  36 +++
 .../apache/activemq/artemis/dto/EntryDTO.java   |  34 +++
 .../activemq/artemis/dto/JMXConnectorDTO.java   | 112 ++++++++
 .../artemis/dto/ManagementContextDTO.java       |  41 +++
 .../apache/activemq/artemis/dto/MatchDTO.java   |  53 ++++
 .../activemq/artemis/dto/RoleAccessDTO.java     |  36 +++
 .../activemq/artemis/dto/WhiteListDTO.java      |  36 +++
 .../org/apache/activemq/artemis/dto/jaxb.index  |   1 +
 .../core/config/JMXConnectorConfiguration.java  | 149 ++++++++++
 .../management/ArtemisMBeanServerBuilder.java   |  90 ++++++
 .../management/ArtemisMBeanServerGuard.java     | 162 +++++++++++
 .../management/ConnectorServerFactory.java      | 282 +++++++++++++++++++
 .../server/management/JMXAccessControlList.java | 203 +++++++++++++
 .../server/management/JaasAuthenticator.java    |  82 ++++++
 .../server/management/MBeanServerFactory.java   | 100 +++++++
 .../server/management/ManagementConnector.java  | 114 ++++++++
 .../server/management/ManagementContext.java    |  74 +++++
 .../server/management/RmiRegistryFactory.java   |  56 ++++
 .../management/JMXAccessControlListTest.java    | 153 ++++++++++
 docs/user-manual/en/management.md               | 147 +++++++++-
 examples/features/standard/jmx/pom.xml          |   1 +
 examples/features/standard/jmx/readme.html      |  14 +-
 .../artemis/jms/example/JMXExample.java         |   8 +-
 .../resources/activemq/server0/management.xml   |  49 ++++
 .../management/DummyLoginModule.java            |  94 +++++++
 .../management/ManagementTestBase.java          |   4 +
 37 files changed, 2493 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Configurable.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Configurable.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Configurable.java
index 9046c8f..9099068 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Configurable.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Configurable.java
@@ -27,9 +27,11 @@ import io.airlift.airline.model.CommandGroupMetadata;
 import io.airlift.airline.model.CommandMetadata;
 import io.airlift.airline.model.GlobalMetadata;
 import org.apache.activemq.artemis.cli.factory.BrokerFactory;
+import org.apache.activemq.artemis.cli.factory.jmx.ManagementFactory;
 import org.apache.activemq.artemis.core.config.FileDeploymentManager;
 import org.apache.activemq.artemis.core.config.impl.FileConfiguration;
 import org.apache.activemq.artemis.dto.BrokerDTO;
+import org.apache.activemq.artemis.dto.ManagementContextDTO;
 import org.apache.activemq.artemis.integration.bootstrap.ActiveMQBootstrapLogger;
 import org.apache.activemq.artemis.jms.server.config.impl.FileJMSConfiguration;
 
@@ -116,6 +118,11 @@ public abstract class Configurable extends ActionAbstract {
       return brokerDTO;
    }
 
+   protected ManagementContextDTO getManagementDTO() throws Exception {
+      String configuration = getManagementConfiguration();
+      return ManagementFactory.createJmxAclConfiguration(configuration, getBrokerHome(), getBrokerInstance(), getBrokerURIInstance());
+   }
+
    protected String getConfiguration() {
       if (configuration == null) {
          File xmlFile = new File(new File(new File(getBrokerInstance()), "etc"), "bootstrap.xml");
@@ -130,4 +137,14 @@ public abstract class Configurable extends ActionAbstract {
       return configuration;
    }
 
+   protected String getManagementConfiguration() {
+      File xmlFile = new File(new File(new File(getBrokerInstance()), "etc"), "management.xml");
+      String configuration = "xml:" + xmlFile.toURI().toString().substring("file:".length());
+
+      // To support Windows paths as explained above.
+      configuration = configuration.replace("\\", "/");
+
+      return configuration;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
index 2897f6d..400bdc3 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
@@ -82,6 +82,7 @@ public class Create extends InputAbstract {
    public static final String ETC_ARTEMIS_PROFILE = "etc/artemis.profile";
    public static final String ETC_LOGGING_PROPERTIES = "etc/logging.properties";
    public static final String ETC_BOOTSTRAP_XML = "etc/bootstrap.xml";
+   public static final String ETC_MANAGEMENT_XML = "etc/management.xml";
    public static final String ETC_BROKER_XML = "etc/broker.xml";
 
    public static final String ETC_ARTEMIS_ROLES_PROPERTIES = "etc/artemis-roles.properties";
@@ -689,6 +690,7 @@ public class Create extends InputAbstract {
       // we want this variable to remain unchanged so that it will use the value set in the profile
       filters.remove("${artemis.instance}");
       write(ETC_BOOTSTRAP_XML, filters, false);
+      write(ETC_MANAGEMENT_XML, filters, false);
       write(ETC_JOLOKIA_ACCESS_XML, filters, false);
 
       context.out.println("");

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java
index 229bd5b..12c00db 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java
@@ -25,10 +25,13 @@ import io.airlift.airline.Option;
 import org.apache.activemq.artemis.cli.Artemis;
 import org.apache.activemq.artemis.cli.commands.tools.LockAbstract;
 import org.apache.activemq.artemis.cli.factory.BrokerFactory;
+import org.apache.activemq.artemis.cli.factory.jmx.ManagementFactory;
 import org.apache.activemq.artemis.cli.factory.security.SecurityManagerFactory;
 import org.apache.activemq.artemis.components.ExternalComponent;
+import org.apache.activemq.artemis.core.server.management.ManagementContext;
 import org.apache.activemq.artemis.dto.BrokerDTO;
 import org.apache.activemq.artemis.dto.ComponentDTO;
+import org.apache.activemq.artemis.dto.ManagementContextDTO;
 import org.apache.activemq.artemis.integration.Broker;
 import org.apache.activemq.artemis.integration.bootstrap.ActiveMQBootstrapLogger;
 import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
@@ -44,6 +47,8 @@ public class Run extends LockAbstract {
 
    public static final ReusableLatch latchRunning = new ReusableLatch(0);
 
+   private ManagementContext managementContext;
+
    /**
     * This will disable the System.exit at the end of the server.stop, as that means there are other things
     * happening on the same VM.
@@ -60,6 +65,9 @@ public class Run extends LockAbstract {
    public Object execute(ActionContext context) throws Exception {
       super.execute(context);
 
+      ManagementContextDTO managementDTO = getManagementDTO();
+      managementContext = ManagementFactory.create(managementDTO);
+
       Artemis.printBanner();
 
       BrokerDTO broker = getBrokerDTO();
@@ -70,6 +78,7 @@ public class Run extends LockAbstract {
 
       server = BrokerFactory.createServer(broker.server, security);
 
+      managementContext.start();
       server.start();
 
       if (broker.web != null) {
@@ -121,11 +130,7 @@ public class Run extends LockAbstract {
             }
             if (file.exists()) {
                try {
-                  try {
-                     server.stop(true);
-                  } catch (Exception e) {
-                     e.printStackTrace();
-                  }
+                  stop();
                   timer.cancel();
                } finally {
                   System.out.println("Server stopped!");
@@ -142,13 +147,20 @@ public class Run extends LockAbstract {
       Runtime.getRuntime().addShutdownHook(new Thread("shutdown-hook") {
          @Override
          public void run() {
-            try {
-               server.stop(true);
-            } catch (Exception e) {
-               e.printStackTrace();
-            }
+            Run.this.stop();
          }
       });
 
    }
+
+   protected void stop() {
+      try {
+         server.stop(true);
+         if (managementContext != null) {
+            managementContext.stop();
+         }
+      } catch (Exception e) {
+         e.printStackTrace();
+      }
+   }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/JmxAclHandler.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/JmxAclHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/JmxAclHandler.java
new file mode 100644
index 0000000..3b13c40
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/JmxAclHandler.java
@@ -0,0 +1,25 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.jmx;
+
+import org.apache.activemq.artemis.dto.ManagementContextDTO;
+
+import java.net.URI;
+
+public interface JmxAclHandler {
+   ManagementContextDTO createJmxAcl(URI configURI, String artemisHome, String artemisInstance, URI artemisURIInstance) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/ManagementFactory.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/ManagementFactory.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/ManagementFactory.java
new file mode 100644
index 0000000..235cdf6
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/ManagementFactory.java
@@ -0,0 +1,134 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.jmx;
+
+
+import org.apache.activemq.artemis.cli.ConfigurationException;
+import org.apache.activemq.artemis.core.config.JMXConnectorConfiguration;
+import org.apache.activemq.artemis.core.server.management.ManagementContext;
+import org.apache.activemq.artemis.dto.AccessDTO;
+import org.apache.activemq.artemis.dto.AuthorisationDTO;
+import org.apache.activemq.artemis.dto.EntryDTO;
+import org.apache.activemq.artemis.dto.JMXConnectorDTO;
+import org.apache.activemq.artemis.dto.ManagementContextDTO;
+import org.apache.activemq.artemis.dto.MatchDTO;
+import org.apache.activemq.artemis.core.server.management.JMXAccessControlList;
+import org.apache.activemq.artemis.utils.FactoryFinder;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.List;
+
+public class ManagementFactory {
+
+   private static ManagementContextDTO createJmxAclConfiguration(URI configURI,
+                                                                 String artemisHome,
+                                                                 String artemisInstance,
+                                                                 URI artemisURIInstance) throws Exception {
+      if (configURI.getScheme() == null) {
+         throw new ConfigurationException("Invalid configuration URI, no scheme specified: " + configURI);
+      }
+
+      JmxAclHandler factory = null;
+      try {
+         FactoryFinder finder = new FactoryFinder("META-INF/services/org/apache/activemq/artemis/broker/jmx/");
+         factory = (JmxAclHandler) finder.newInstance(configURI.getScheme());
+      } catch (IOException ioe) {
+         throw new ConfigurationException("Invalid configuration URI, can't find configuration scheme: " + configURI.getScheme());
+      }
+      return factory.createJmxAcl(configURI, artemisHome, artemisInstance, artemisURIInstance);
+   }
+
+   public static ManagementContextDTO createJmxAclConfiguration(String configuration,
+                                                                String artemisHome,
+                                                                String artemisInstance,
+                                                                URI artemisURIInstance) throws Exception {
+      return createJmxAclConfiguration(new URI(configuration), artemisHome, artemisInstance, artemisURIInstance);
+   }
+
+   public static ManagementContext create(ManagementContextDTO config) {
+      ManagementContext context = new ManagementContext();
+
+      if (config.getAuthorisation() != null) {
+         AuthorisationDTO authorisation = config.getAuthorisation();
+         JMXAccessControlList accessControlList = new JMXAccessControlList();
+         List<EntryDTO> entries = authorisation.getWhiteList().getEntries();
+         for (EntryDTO entry : entries) {
+            accessControlList.addToWhiteList(entry.domain, entry.key);
+         }
+
+         List<AccessDTO> accessList = authorisation.getDefaultAccess().getAccess();
+         for (AccessDTO access : accessList) {
+            String[] split = access.roles.split(",");
+            accessControlList.addToDefaultAccess(access.method, split);
+         }
+
+         List<MatchDTO> matches = authorisation.getRoleAccess().getMatch();
+         for (MatchDTO match : matches) {
+            List<AccessDTO> accesses = match.getAccess();
+            for (AccessDTO access : accesses) {
+               String[] split = access.roles.split(",");
+               accessControlList.addToRoleAccess(match.getDomain(), match.getKey(), access.method, split);
+            }
+         }
+         context.setAccessControlList(accessControlList);
+      }
+
+      if (config.getJmxConnector() != null) {
+         JMXConnectorDTO jmxConnector = config.getJmxConnector();
+         JMXConnectorConfiguration jmxConnectorConfiguration = new JMXConnectorConfiguration();
+
+         jmxConnectorConfiguration.setConnectorPort(jmxConnector.getConnectorPort());
+         if (jmxConnector.getConnectorHost() != null) {
+            jmxConnectorConfiguration.setConnectorHost(jmxConnector.getConnectorHost());
+         }
+         if (jmxConnector.getJmxRealm() != null) {
+            jmxConnectorConfiguration.setJmxRealm(jmxConnector.getJmxRealm());
+         }
+         if (jmxConnector.getAuthenticatorType() != null) {
+            jmxConnectorConfiguration.setAuthenticatorType(jmxConnector.getAuthenticatorType());
+         }
+         if (jmxConnector.getKeyStorePath() != null) {
+            jmxConnectorConfiguration.setKeyStorePath(jmxConnector.getKeyStorePath());
+         }
+         if (jmxConnector.getKeyStoreProvider() != null) {
+            jmxConnectorConfiguration.setKeyStoreProvider(jmxConnector.getKeyStoreProvider());
+         }
+         if (jmxConnector.getKeyStorePassword() != null) {
+            jmxConnectorConfiguration.setKeyStorePassword(jmxConnector.getKeyStorePassword());
+         }
+         if (jmxConnector.getTrustStorePath() != null) {
+            jmxConnectorConfiguration.setTrustStorePath(jmxConnector.getTrustStorePath());
+         }
+         if (jmxConnector.getTrustStoreProvider() != null) {
+            jmxConnectorConfiguration.setTrustStoreProvider(jmxConnector.getTrustStoreProvider());
+         }
+         if (jmxConnector.getTrustStorePassword() != null) {
+            jmxConnectorConfiguration.setTrustStorePassword(jmxConnector.getTrustStorePassword());
+         }
+         if (jmxConnector.getObjectName() != null) {
+            jmxConnectorConfiguration.setObjectName(jmxConnector.getObjectName());
+         }
+         if (jmxConnector.isSecured() != null) {
+            jmxConnectorConfiguration.setSecured(jmxConnector.isSecured());
+         }
+         context.setJmxConnectorConfiguration(jmxConnectorConfiguration);
+      }
+
+      return context;
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/XmlJmxAclHandler.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/XmlJmxAclHandler.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/XmlJmxAclHandler.java
new file mode 100644
index 0000000..2ce8205
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/XmlJmxAclHandler.java
@@ -0,0 +1,36 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.jmx;
+
+
+import org.apache.activemq.artemis.cli.ConfigurationException;
+import org.apache.activemq.artemis.dto.ManagementContextDTO;
+import org.apache.activemq.artemis.dto.XmlUtil;
+
+import java.io.File;
+import java.net.URI;
+
+public class XmlJmxAclHandler implements JmxAclHandler {
+   @Override
+   public ManagementContextDTO createJmxAcl(URI configURI, String artemisHome, String artemisInstance, URI artemisURIInstance) throws Exception {
+      File file = new File(configURI.getSchemeSpecificPart());
+      if (!file.exists()) {
+         throw new ConfigurationException("Invalid configuration URI, can't find file: " + file.getName());
+      }
+      return XmlUtil.decode(ManagementContextDTO.class, file, artemisHome, artemisInstance, artemisURIInstance);
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/jmx/xml
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/jmx/xml b/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/jmx/xml
new file mode 100644
index 0000000..3d2dd01
--- /dev/null
+++ b/artemis-cli/src/main/resources/META-INF/services/org/apache/activemq/artemis/broker/jmx/xml
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+class=org.apache.activemq.artemis.cli.factory.jmx.XmlJmxAclHandler
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/management.xml
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/management.xml b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/management.xml
new file mode 100644
index 0000000..1dd7510
--- /dev/null
+++ b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/management.xml
@@ -0,0 +1,49 @@
+<?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.
+  -->
+<management-context xmlns="http://activemq.org/schema">
+   <!--<connector connector-port="1099"/>-->
+   <authorisation>
+      <whitelist>
+         <entry domain="hawtio"/>
+      </whitelist>
+      <default-access>
+         <access method="list*" roles="view,update,amq"/>
+         <access method="get*" roles="view,update,amq"/>
+         <access method="is*" roles="view,update,amq"/>
+         <access method="set*" roles="update,amq"/>
+         <access method="*" roles="amq"/>
+      </default-access>
+      <role-access>
+         <match domain="org.apache.activemq.apache">
+            <access method="list*" roles="view,update,amq"/>
+            <access method="get*" roles="view,update,amq"/>
+            <access method="is*" roles="view,update,amq"/>
+            <access method="set*" roles="update,amq"/>
+            <access method="*" roles="amq"/>
+         </match>
+         <!--example of how to configure a specific object-->
+         <!--<match domain="org.apache.activemq.apache" key="subcomponent=queues">
+            <access method="list*" roles="view,update,amq"/>
+            <access method="get*" roles="view,update,amq"/>
+            <access method="is*" roles="view,update,amq"/>
+            <access method="set*" roles="update,amq"/>
+            <access method="*" roles="amq"/>
+         </match>-->
+      </role-access>
+   </authorisation>
+</management-context>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java b/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java
index c802fb2..fcf1e67 100644
--- a/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java
+++ b/artemis-cli/src/test/java/org/apache/activemq/cli/test/StreamClassPathTest.java
@@ -39,6 +39,7 @@ public class StreamClassPathTest {
       openStream(Create.ETC_ARTEMIS_PROFILE);
       openStream(Create.ETC_LOGGING_PROPERTIES);
       openStream(Create.ETC_BOOTSTRAP_XML);
+      openStream(Create.ETC_MANAGEMENT_XML);
       openStream(Create.ETC_BROKER_XML);
       openStream(Create.ETC_ARTEMIS_ROLES_PROPERTIES);
       openStream(Create.ETC_ARTEMIS_USERS_PROPERTIES);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/AccessDTO.java
----------------------------------------------------------------------
diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/AccessDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/AccessDTO.java
new file mode 100644
index 0000000..dc1f614
--- /dev/null
+++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/AccessDTO.java
@@ -0,0 +1,34 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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 = "access")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class AccessDTO {
+
+   @XmlAttribute
+   public String method;
+
+   @XmlAttribute
+   public String roles;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/AuthorisationDTO.java
----------------------------------------------------------------------
diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/AuthorisationDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/AuthorisationDTO.java
new file mode 100644
index 0000000..dd30246
--- /dev/null
+++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/AuthorisationDTO.java
@@ -0,0 +1,49 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "authorisation")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class AuthorisationDTO {
+
+   @XmlElementRef
+   WhiteListDTO whitelist;
+
+   @XmlElementRef
+   DefaultAccessDTO defaultAccess;
+
+   @XmlElementRef
+   RoleAccessDTO roleAccess;
+
+   public WhiteListDTO getWhiteList() {
+      return whitelist;
+   }
+
+   public DefaultAccessDTO getDefaultAccess() {
+      return defaultAccess;
+   }
+
+   public RoleAccessDTO getRoleAccess() {
+      return roleAccess;
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/DefaultAccessDTO.java
----------------------------------------------------------------------
diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/DefaultAccessDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/DefaultAccessDTO.java
new file mode 100644
index 0000000..c1db6e3
--- /dev/null
+++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/DefaultAccessDTO.java
@@ -0,0 +1,36 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.List;
+
+@XmlRootElement(name = "default-access")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class DefaultAccessDTO {
+
+   @XmlElementRef
+   List<AccessDTO> access;
+
+   public List<AccessDTO> getAccess() {
+      return access;
+   }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/EntryDTO.java
----------------------------------------------------------------------
diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/EntryDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/EntryDTO.java
new file mode 100644
index 0000000..e938a42
--- /dev/null
+++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/EntryDTO.java
@@ -0,0 +1,34 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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 = "entry")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class EntryDTO {
+
+   @XmlAttribute
+   public String domain;
+
+   @XmlAttribute
+   public String key;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/JMXConnectorDTO.java
----------------------------------------------------------------------
diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/JMXConnectorDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/JMXConnectorDTO.java
new file mode 100644
index 0000000..617a570
--- /dev/null
+++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/JMXConnectorDTO.java
@@ -0,0 +1,112 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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 = "connector")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class JMXConnectorDTO {
+
+   @XmlAttribute  (name = "connector-host")
+   String connectorHost;
+
+   @XmlAttribute  (name = "connector-port", required = true)
+   Integer connectorPort;
+
+   @XmlAttribute  (name = "jmx-realm")
+   String jmxRealm;
+
+   @XmlAttribute  (name = "object-name")
+   String objectName;
+
+   @XmlAttribute (name = "authenticator-type")
+   String authenticatorType;
+
+   @XmlAttribute (name = "secured")
+   Boolean secured;
+
+   @XmlAttribute (name = "key-store-provider")
+   String keyStoreProvider;
+
+   @XmlAttribute (name = "key-store-path")
+   String keyStorePath;
+
+   @XmlAttribute (name = "key-store-password")
+   String keyStorePassword;
+
+   @XmlAttribute (name = "trust-store-provider")
+   String trustStoreProvider;
+
+   @XmlAttribute (name = "trust-store-path")
+   String trustStorePath;
+
+   @XmlAttribute (name = "trust-store-password")
+   String trustStorePassword;
+
+   public String getConnectorHost() {
+      return connectorHost;
+   }
+
+   public int getConnectorPort() {
+      return connectorPort;
+   }
+
+   public String getJmxRealm() {
+      return jmxRealm;
+   }
+
+   public String getObjectName() {
+      return objectName;
+   }
+
+   public String getAuthenticatorType() {
+      return authenticatorType;
+   }
+
+   public Boolean isSecured() {
+      return secured;
+   }
+
+   public String getKeyStoreProvider() {
+      return keyStoreProvider;
+   }
+
+   public String getKeyStorePath() {
+      return keyStorePath;
+   }
+
+   public String getKeyStorePassword() {
+      return keyStorePassword;
+   }
+
+   public String getTrustStoreProvider() {
+      return trustStoreProvider;
+   }
+
+   public String getTrustStorePath() {
+      return trustStorePath;
+   }
+
+   public String getTrustStorePassword() {
+      return trustStorePassword;
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/ManagementContextDTO.java
----------------------------------------------------------------------
diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/ManagementContextDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/ManagementContextDTO.java
new file mode 100644
index 0000000..7594127
--- /dev/null
+++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/ManagementContextDTO.java
@@ -0,0 +1,41 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "management-context")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ManagementContextDTO {
+
+   @XmlElementRef (required = false)
+   JMXConnectorDTO jmxConnector;
+
+   @XmlElementRef (required = false)
+   AuthorisationDTO authorisation;
+
+   public JMXConnectorDTO getJmxConnector() {
+      return jmxConnector;
+   }
+
+   public AuthorisationDTO getAuthorisation() {
+      return authorisation;
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/MatchDTO.java
----------------------------------------------------------------------
diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/MatchDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/MatchDTO.java
new file mode 100644
index 0000000..77e8b01
--- /dev/null
+++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/MatchDTO.java
@@ -0,0 +1,53 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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 = "match")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class MatchDTO {
+
+
+   @XmlAttribute
+   public String domain;
+
+   @XmlAttribute
+   public String key;
+
+   @XmlElementRef
+   List<AccessDTO> access;
+
+   public String getDomain() {
+      return domain;
+   }
+
+   public String getKey() {
+      return key;
+   }
+
+   public List<AccessDTO> getAccess() {
+      return access;
+   }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/RoleAccessDTO.java
----------------------------------------------------------------------
diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/RoleAccessDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/RoleAccessDTO.java
new file mode 100644
index 0000000..ca763d4
--- /dev/null
+++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/RoleAccessDTO.java
@@ -0,0 +1,36 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.List;
+
+@XmlRootElement(name = "role-access")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RoleAccessDTO {
+
+   @XmlElementRef
+   List<MatchDTO> match;
+
+   public List<MatchDTO> getMatch() {
+      return match;
+   }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WhiteListDTO.java
----------------------------------------------------------------------
diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WhiteListDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WhiteListDTO.java
new file mode 100644
index 0000000..70feabe
--- /dev/null
+++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WhiteListDTO.java
@@ -0,0 +1,36 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.List;
+
+@XmlRootElement(name = "whitelist")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class WhiteListDTO {
+
+   @XmlElementRef
+   List<EntryDTO> entry;
+
+   public List<EntryDTO> getEntries() {
+      return entry;
+   }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-dto/src/main/resources/org/apache/activemq/artemis/dto/jaxb.index
----------------------------------------------------------------------
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 94f0b2d..73ff377 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,4 +17,5 @@
 BrokerDTO
 SecurityDTO
 JaasSecurityDTO
+ManagementContextDTO
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/JMXConnectorConfiguration.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/JMXConnectorConfiguration.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/JMXConnectorConfiguration.java
new file mode 100644
index 0000000..786f554
--- /dev/null
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/JMXConnectorConfiguration.java
@@ -0,0 +1,149 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.core.config;
+
+public class JMXConnectorConfiguration {
+   private int rmiRegistryPort;
+   private String connectorHost = "localhost";
+   private int connectorPort = 1099;
+
+   private String connectorPath = "/jmxrmi";
+
+   private String jmxRealm = "activemq";
+   private String objectName = "connector:name=rmi";
+   private String authenticatorType = "password";
+   private boolean secured =  false;
+   private String keyStoreProvider;
+   private String keyStorePath;
+   private String keyStorePassword;
+   private String trustStoreProvider;
+   private String trustStorePath;
+   private String trustStorePassword;
+
+   public int getRmiRegistryPort() {
+      return rmiRegistryPort;
+   }
+
+   public void setRmiRegistryPort(int rmiRegistryPort) {
+      this.rmiRegistryPort = rmiRegistryPort;
+   }
+
+   public String getConnectorHost() {
+      return connectorHost;
+   }
+
+   public void setConnectorHost(String connectorHost) {
+      this.connectorHost = connectorHost;
+   }
+
+   public int getConnectorPort() {
+      return connectorPort;
+   }
+
+   public void setConnectorPort(int connectorPort) {
+      this.connectorPort = connectorPort;
+   }
+
+   public String getJmxRealm() {
+      return jmxRealm;
+   }
+
+   public void setJmxRealm(String jmxRealm) {
+      this.jmxRealm = jmxRealm;
+   }
+
+   public String getServiceUrl() {
+      String rmiServer = "";
+      if (rmiRegistryPort != 0) {
+         // This is handy to use if you have a firewall and need to force JMX to use fixed ports.
+         rmiServer = "" + getConnectorHost() + ":" + rmiRegistryPort;
+      }
+      return "service:jmx:rmi://" + rmiServer + "/jndi/rmi://" + getConnectorHost() + ":" + connectorPort + connectorPath;
+   }
+
+   public String getAuthenticatorType() {
+      return authenticatorType;
+   }
+
+   public void setAuthenticatorType(String authenticatorType) {
+      this.authenticatorType = authenticatorType;
+   }
+
+   public boolean isSecured() {
+      return secured;
+   }
+
+   public String getKeyStoreProvider() {
+      return keyStoreProvider;
+   }
+
+   public void setKeyStoreProvider(String keyStoreProvider) {
+      this.keyStoreProvider = keyStoreProvider;
+   }
+
+   public String getKeyStorePath() {
+      return keyStorePath;
+   }
+
+   public void setKeyStorePath(String keyStorePath) {
+      this.keyStorePath = keyStorePath;
+   }
+
+   public String getKeyStorePassword() {
+      return keyStorePassword;
+   }
+
+   public void setKeyStorePassword(String keyStorePassword) {
+      this.keyStorePassword = keyStorePassword;
+   }
+
+   public String getTrustStoreProvider() {
+      return trustStoreProvider;
+   }
+
+   public void setTrustStoreProvider(String trustStoreProvider) {
+      this.trustStoreProvider = trustStoreProvider;
+   }
+
+   public String getTrustStorePath() {
+      return trustStorePath;
+   }
+
+   public void setTrustStorePath(String trustStorePath) {
+      this.trustStorePath = trustStorePath;
+   }
+
+   public String getTrustStorePassword() {
+      return trustStorePassword;
+   }
+
+   public void setTrustStorePassword(String trustStorePassword) {
+      this.trustStorePassword = trustStorePassword;
+   }
+
+   public void setObjectName(String objectName) {
+      this.objectName = objectName;
+   }
+
+   public String getObjectName() {
+      return objectName;
+   }
+
+   public void setSecured(Boolean secured) {
+      this.secured = secured;
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/ArtemisMBeanServerBuilder.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/ArtemisMBeanServerBuilder.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/ArtemisMBeanServerBuilder.java
new file mode 100644
index 0000000..e4e743b
--- /dev/null
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/ArtemisMBeanServerBuilder.java
@@ -0,0 +1,90 @@
+/*
+ * 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.core.server.management;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerBuilder;
+import javax.management.MBeanServerDelegate;
+
+public class ArtemisMBeanServerBuilder extends MBeanServerBuilder {
+
+   private static volatile InvocationHandler guard;
+
+   public static void setGuard(InvocationHandler guardHandler) {
+      guard = guardHandler;
+   }
+
+   public static ArtemisMBeanServerGuard getArtemisMBeanServerGuard() {
+      return (ArtemisMBeanServerGuard) guard;
+   }
+
+   @Override
+   public MBeanServer newMBeanServer(String defaultDomain, MBeanServer outer, MBeanServerDelegate delegate) {
+      InvocationHandler handler = new MBeanInvocationHandler(super.newMBeanServer(defaultDomain, outer, delegate));
+      return (MBeanServer) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{MBeanServer.class}, handler);
+   }
+
+   private static final class MBeanInvocationHandler implements InvocationHandler {
+
+      private final MBeanServer wrapped;
+      private final List<String> guarded = Collections.unmodifiableList(Arrays.asList("invoke", "getAttribute", "getAttributes", "setAttribute", "setAttributes"));
+
+      MBeanInvocationHandler(MBeanServer mbeanServer) {
+         wrapped = mbeanServer;
+      }
+
+      @Override
+      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+         if (guarded.contains(method.getName())) {
+            if (ArtemisMBeanServerBuilder.guard == null) {
+               throw new IllegalStateException("ArtemisMBeanServerBuilder not initialized");
+            }
+            guard.invoke(proxy, method, args);
+         }
+         if (method.getName().equals("queryMBeans")) {
+            guard.invoke(wrapped, method, args);
+         }
+         if (method.getName().equals("equals")
+               && method.getParameterTypes().length == 1
+               && method.getParameterTypes()[0] == Object.class) {
+            Object target = args[0];
+            if (target != null && Proxy.isProxyClass(target.getClass())) {
+               InvocationHandler handler = Proxy.getInvocationHandler(target);
+               if (handler instanceof MBeanInvocationHandler) {
+                  args[0] = ((MBeanInvocationHandler) handler).wrapped;
+               }
+            }
+         } else if (method.getName().equals("finalize") && method.getParameterTypes().length == 0) {
+            // special case finalize, don't route through to delegate because that will get its own call
+            return null;
+         }
+         try {
+            return method.invoke(wrapped, args);
+         } catch (InvocationTargetException ite) {
+            throw ite.getCause();
+         }
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/ArtemisMBeanServerGuard.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/ArtemisMBeanServerGuard.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/ArtemisMBeanServerGuard.java
new file mode 100644
index 0000000..115b31a
--- /dev/null
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/ArtemisMBeanServerGuard.java
@@ -0,0 +1,162 @@
+/*
+ * 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.core.server.management;
+
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.JMException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.security.auth.Subject;
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Principal;
+import java.util.List;
+
+public class ArtemisMBeanServerGuard implements InvocationHandler {
+
+   private JMXAccessControlList jmxAccessControlList = JMXAccessControlList.createDefaultList();
+
+   public void init() {
+      ArtemisMBeanServerBuilder.setGuard(this);
+   }
+
+   @Override
+   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+      if (method.getParameterTypes().length == 0)
+         return null;
+
+      if (!ObjectName.class.isAssignableFrom(method.getParameterTypes()[0]))
+         return null;
+
+      ObjectName objectName = (ObjectName) args[0];
+      if ("getAttribute".equals(method.getName())) {
+         handleGetAttribute((MBeanServer) proxy, objectName, (String) args[1]);
+      } else if ("getAttributes".equals(method.getName())) {
+         handleGetAttributes((MBeanServer) proxy, objectName, (String[]) args[1]);
+      } else if ("setAttribute".equals(method.getName())) {
+         handleSetAttribute((MBeanServer) proxy, objectName, (Attribute) args[1]);
+      } else if ("setAttributes".equals(method.getName())) {
+         handleSetAttributes((MBeanServer) proxy, objectName, (AttributeList) args[1]);
+      } else if ("invoke".equals(method.getName())) {
+         handleInvoke(objectName, (String) args[1], (Object[]) args[2], (String[]) args[3]);
+      }
+
+      return null;
+   }
+
+   private void handleGetAttribute(MBeanServer proxy, ObjectName objectName, String attributeName) throws JMException, IOException {
+      MBeanInfo info = proxy.getMBeanInfo(objectName);
+      String prefix = null;
+      for (MBeanAttributeInfo attr : info.getAttributes()) {
+         if (attr.getName().equals(attributeName)) {
+            prefix = attr.isIs() ? "is" : "get";
+         }
+      }
+      if (prefix == null) {
+         //ActiveMQServerLogger.LOGGER.debug("Attribute " + attributeName + " can not be found for MBean " + objectName.toString());
+      } else {
+         handleInvoke(objectName, prefix + attributeName, new Object[]{}, new String[]{});
+      }
+   }
+
+   private void handleGetAttributes(MBeanServer proxy, ObjectName objectName, String[] attributeNames) throws JMException, IOException {
+      for (String attr : attributeNames) {
+         handleGetAttribute(proxy, objectName, attr);
+      }
+   }
+
+   private void handleSetAttribute(MBeanServer proxy, ObjectName objectName, Attribute attribute) throws JMException, IOException {
+      String dataType = null;
+      MBeanInfo info = proxy.getMBeanInfo(objectName);
+      for (MBeanAttributeInfo attr : info.getAttributes()) {
+         if (attr.getName().equals(attribute.getName())) {
+            dataType = attr.getType();
+            break;
+         }
+      }
+
+      if (dataType == null)
+         throw new IllegalStateException("Attribute data type can not be found");
+
+      handleInvoke(objectName, "set" + attribute.getName(), new Object[]{attribute.getValue()}, new String[]{dataType});
+   }
+
+   private void handleSetAttributes(MBeanServer proxy, ObjectName objectName, AttributeList attributes) throws JMException, IOException {
+      for (Attribute attr : attributes.asList()) {
+         handleSetAttribute(proxy, objectName, attr);
+      }
+   }
+
+   private boolean canBypassRBAC(ObjectName objectName) {
+      return jmxAccessControlList.isInWhiteList(objectName);
+   }
+
+   void handleInvoke(ObjectName objectName, String operationName, Object[] params, String[] signature) throws IOException {
+      if (canBypassRBAC(objectName)) {
+         return;
+      }
+      List<String> requiredRoles = getRequiredRoles(objectName, operationName, params, signature);
+      for (String role : requiredRoles) {
+         if (currentUserHasRole(role))
+            return;
+      }
+      throw new SecurityException("Insufficient roles/credentials for operation");
+   }
+
+   List<String> getRequiredRoles(ObjectName objectName, String methodName, Object[] params, String[] signature) throws IOException {
+      return jmxAccessControlList.getRolesForObject(objectName, methodName);
+   }
+
+   public void setJMXAccessControlList(JMXAccessControlList JMXAccessControlList) {
+      this.jmxAccessControlList = JMXAccessControlList;
+   }
+
+   public static boolean currentUserHasRole(String requestedRole) {
+
+      String clazz;
+      String role;
+      int index = requestedRole.indexOf(':');
+      if (index > 0) {
+         clazz = requestedRole.substring(0, index);
+         role = requestedRole.substring(index + 1);
+      } else {
+         clazz = "org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal";
+         role = requestedRole;
+      }
+      AccessControlContext acc = AccessController.getContext();
+      if (acc == null) {
+         return false;
+      }
+      Subject subject = Subject.getSubject(acc);
+      if (subject == null) {
+         return false;
+      }
+      for (Principal p : subject.getPrincipals()) {
+         if (clazz.equals(p.getClass().getName()) && role.equals(p.getName())) {
+            return true;
+         }
+      }
+      return false;
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/ConnectorServerFactory.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/ConnectorServerFactory.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/ConnectorServerFactory.java
new file mode 100644
index 0000000..2c66acb
--- /dev/null
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/ConnectorServerFactory.java
@@ -0,0 +1,282 @@
+/*
+ * 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.core.server.management;
+
+import org.apache.activemq.artemis.core.remoting.impl.ssl.SSLSupport;
+
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnectorServer;
+import javax.net.ServerSocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.rmi.ssl.SslRMIClientSocketFactory;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.util.Map;
+
+public class ConnectorServerFactory {
+
+   public void setkeyStoreProvider(String keyStoreProvider) {
+      this.keyStoreProvider = keyStoreProvider;
+   }
+
+   public void setKeyStorePassword(String keyStorePassword) {
+      this.keyStorePassword = keyStorePassword;
+   }
+
+   public void setTrustStorePath(String trustStorePath) {
+      this.trustStorePath = trustStorePath;
+   }
+
+   public void setTrustStoreProvider(String trustStoreProvider) {
+      this.trustStoreProvider = trustStoreProvider;
+   }
+
+   public void setTrustStorePassword(String trustStorePassword) {
+      this.trustStorePassword = trustStorePassword;
+   }
+
+   private enum AuthenticatorType { NONE, PASSWORD, CERTIFICATE };
+
+   private MBeanServer server;
+   private String serviceUrl;
+   private String rmiServerHost;
+   private Map environment;
+   private ObjectName objectName;
+   private JMXConnectorServer connectorServer;
+
+   private AuthenticatorType authenticatorType = AuthenticatorType.PASSWORD;
+
+   private boolean secured;
+
+   private String keyStoreProvider;
+
+   private String keyStorePath;
+
+   private String keyStorePassword;
+
+   private String trustStoreProvider;
+
+   private String trustStorePath;
+
+   private String trustStorePassword;
+
+
+   public String getKeyStoreProvider() {
+      return keyStoreProvider;
+   }
+
+   public String getKeyStorePath() {
+      return keyStorePath;
+   }
+
+   public void setKeyStorePath(String keyStorePath) {
+      this.keyStorePath = keyStorePath;
+   }
+
+   public String getKeyStorePassword() {
+      return keyStorePassword;
+   }
+
+   public String getTrustStoreProvider() {
+      return trustStoreProvider;
+   }
+
+   public String getTrustStorePath() {
+      return trustStorePath;
+   }
+
+   public String getTrustStorePassword() {
+      return trustStorePassword;
+   }
+
+   public MBeanServer getServer() {
+      return server;
+   }
+
+   public void setServer(MBeanServer server) {
+      this.server = server;
+   }
+
+   public String getServiceUrl() {
+      return serviceUrl;
+   }
+
+   public void setServiceUrl(String serviceUrl) {
+      this.serviceUrl = serviceUrl;
+   }
+
+   public String getRmiServerHost() {
+      return this.rmiServerHost;
+   }
+
+   public void setRmiServerHost(String rmiServerHost) {
+      this.rmiServerHost = rmiServerHost;
+   }
+
+   public Map getEnvironment() {
+      return environment;
+   }
+
+   public void setEnvironment(Map environment) {
+      this.environment = environment;
+   }
+
+   public ObjectName getObjectName() {
+      return objectName;
+   }
+
+   public void setObjectName(ObjectName objectName) {
+      this.objectName = objectName;
+   }
+
+   public String getAuthenticatorType() {
+      return this.authenticatorType.name().toLowerCase();
+   }
+
+   /**
+    * Authenticator type to use. Acceptable values are "none", "password", and "certificate"
+    *
+    * @param value
+    */
+   public void setAuthenticatorType(String value) {
+      this.authenticatorType = AuthenticatorType.valueOf(value.toUpperCase());
+   }
+
+   public boolean isSecured() {
+      return this.secured;
+   }
+
+   public void setSecured(boolean secured) {
+      this.secured = secured;
+   }
+
+   private boolean isClientAuth() {
+      return this.authenticatorType.equals(AuthenticatorType.CERTIFICATE);
+   }
+
+   public void init() throws Exception {
+
+      if (this.server == null) {
+         throw new IllegalArgumentException("server must be set");
+      }
+      JMXServiceURL url = new JMXServiceURL(this.serviceUrl);
+      setupArtemisRMIServerSocketFactory();
+      if (isClientAuth()) {
+         this.secured = true;
+      }
+
+      if (this.secured) {
+         this.setupSsl();
+      }
+
+      if (!AuthenticatorType.PASSWORD.equals(this.authenticatorType)) {
+         this.environment.remove("jmx.remote.authenticator");
+      }
+
+      this.connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, this.environment, this.server);
+      if (this.objectName != null) {
+         this.server.registerMBean(this.connectorServer, this.objectName);
+      }
+
+      try {
+         this.connectorServer.start();
+      } catch (Exception ex) {
+         doUnregister(this.objectName);
+         throw ex;
+      }
+   }
+
+   public void destroy() throws Exception {
+      try {
+         if (this.connectorServer != null) {
+            this.connectorServer.stop();
+         }
+      } finally {
+         doUnregister(this.objectName);
+      }
+   }
+
+   protected void doUnregister(ObjectName objectName) {
+      try {
+         if (this.objectName != null && this.server.isRegistered(objectName)) {
+            this.server.unregisterMBean(objectName);
+         }
+      } catch (JMException ex) {
+         // Ignore
+      }
+   }
+
+   //todo fix
+   private void setupSsl() throws Exception {
+      SSLContext context = SSLSupport.createContext(keyStoreProvider, keyStorePath, keyStorePassword, trustStoreProvider, trustStorePath, trustStorePassword);
+      SSLServerSocketFactory sssf = context.getServerSocketFactory();
+      RMIServerSocketFactory rssf = new ArtemisSslRMIServerSocketFactory(sssf, this.isClientAuth(), rmiServerHost);
+      RMIClientSocketFactory rcsf = new SslRMIClientSocketFactory();
+      environment.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, rssf);
+      environment.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, rcsf);
+   }
+
+   private void setupArtemisRMIServerSocketFactory() {
+      RMIServerSocketFactory rmiServerSocketFactory = new ArtemisRMIServerSocketFactory(getRmiServerHost());
+      environment.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, rmiServerSocketFactory);
+   }
+
+   private static class ArtemisSslRMIServerSocketFactory implements RMIServerSocketFactory {
+      private SSLServerSocketFactory sssf;
+      private boolean clientAuth;
+      private String rmiServerHost;
+
+      ArtemisSslRMIServerSocketFactory(SSLServerSocketFactory sssf, boolean clientAuth, String rmiServerHost) {
+         this.sssf = sssf;
+         this.clientAuth = clientAuth;
+         this.rmiServerHost = rmiServerHost;
+      }
+
+      @Override
+      public ServerSocket createServerSocket(int port) throws IOException {
+         SSLServerSocket ss = (SSLServerSocket) sssf.createServerSocket(port, 50, InetAddress.getByName(rmiServerHost));
+         ss.setNeedClientAuth(clientAuth);
+         return ss;
+      }
+   }
+
+   private static class ArtemisRMIServerSocketFactory implements RMIServerSocketFactory {
+      private String rmiServerHost;
+
+      ArtemisRMIServerSocketFactory(String rmiServerHost) {
+         this.rmiServerHost = rmiServerHost;
+      }
+
+      @Override
+      public ServerSocket createServerSocket(int port) throws IOException {
+         ServerSocket serverSocket = (ServerSocket) ServerSocketFactory.getDefault().createServerSocket(port, 50, InetAddress.getByName(rmiServerHost));
+         return serverSocket;
+      }
+   }
+
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/JMXAccessControlList.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/JMXAccessControlList.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/JMXAccessControlList.java
new file mode 100644
index 0000000..0cafeb0
--- /dev/null
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/JMXAccessControlList.java
@@ -0,0 +1,203 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.core.server.management;
+
+import javax.management.ObjectName;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class JMXAccessControlList {
+
+   private Access defaultAccess = new Access("*");
+   private Map<String, Access> domainAccess = new HashMap<>();
+   private ConcurrentHashMap<String, List<String>> whitelist = new ConcurrentHashMap<>();
+
+
+   public void addToWhiteList(String domain, String match) {
+      List<String> list = new ArrayList<>();
+      list = whitelist.putIfAbsent(domain, list);
+      if (list == null) {
+         list = whitelist.get(domain);
+      }
+      list.add(match != null ? match : "*");
+   }
+
+
+   public List<String> getRolesForObject(ObjectName objectName, String methodName) {
+      Hashtable<String, String> keyPropertyList = objectName.getKeyPropertyList();
+      for (Map.Entry<String, String> keyEntry : keyPropertyList.entrySet()) {
+         String key = keyEntry.getKey() + "=" + keyEntry.getValue();
+         Access access = domainAccess.get(getObjectID(objectName.getDomain(), key));
+         if (access != null) {
+            return access.getMatchingRolesForMethod(methodName);
+         }
+      }
+      for (Map.Entry<String, String> keyEntry : keyPropertyList.entrySet()) {
+         String key = keyEntry.getKey() + "=*";
+         Access access = domainAccess.get(getObjectID(objectName.getDomain(), key));
+         if (access != null) {
+            return access.getMatchingRolesForMethod(methodName);
+         }
+      }
+      Access access = domainAccess.get(objectName.getDomain());
+      if (access == null) {
+         access = defaultAccess;
+      }
+      return access.getMatchingRolesForMethod(methodName);
+   }
+
+   public boolean isInWhiteList(ObjectName objectName) {
+      List<String> matches = whitelist.get(objectName.getDomain());
+      if (matches != null) {
+         for (String match : matches) {
+            if (match.equals("*")) {
+               return true;
+            } else {
+               String[] split = match.split("=");
+               String key = split[0];
+               String val = split[1];
+               String propVal = objectName.getKeyProperty(key);
+               if (propVal != null && (val.equals("*") || propVal.equals(val))) {
+                  return true;
+               }
+            }
+         }
+      }
+      return false;
+   }
+
+   public void addToDefaultAccess(String method, String... roles) {
+      if (roles != null) {
+         if ( method.equals("*")) {
+            defaultAccess.addCatchAll(roles);
+         } else if (method.endsWith("*")) {
+            String prefix = method.replace("*", "");
+            defaultAccess.addMethodsPrefixes(prefix, roles);
+         } else {
+            defaultAccess.addMethods(method, roles);
+         }
+      }
+   }
+
+   public void addToRoleAccess(String domain,String key, String method, String... roles) {
+      String id = getObjectID(domain, key);
+      Access access = domainAccess.get(id);
+      if (access == null) {
+         access = new Access(domain);
+         domainAccess.put(id, access);
+      }
+
+      if (method.endsWith("*")) {
+         String prefix = method.replace("*", "");
+         access.addMethodsPrefixes(prefix, roles);
+      } else {
+         access.addMethods(method, roles);
+      }
+   }
+
+   private String getObjectID(String domain, String key) {
+      String id = domain;
+
+      if (key != null) {
+         String actualKey = key;
+         if (key.endsWith("\"")) {
+            actualKey = actualKey.replace("\"", "");
+         }
+         id += ":" + actualKey;
+      }
+      return id;
+   }
+
+   static class Access {
+      private final String domain;
+      List<String> catchAllRoles = new ArrayList<>();
+      Map<String, List<String>> methodRoles = new HashMap<>();
+      Map<String, List<String>> methodPrefixRoles = new HashMap<>();
+
+      Access(String domain) {
+         this.domain = domain;
+      }
+
+      public synchronized void addMethods(String prefix, String... roles) {
+         List<String> rolesList = methodRoles.get(prefix);
+         if (rolesList == null) {
+            rolesList = new ArrayList<>();
+            methodRoles.put(prefix, rolesList);
+         }
+         for (String role : roles) {
+            rolesList.add(role);
+         }
+      }
+
+      public synchronized void addMethodsPrefixes(String prefix, String... roles) {
+         List<String> rolesList = methodPrefixRoles.get(prefix);
+         if (rolesList == null) {
+            rolesList = new ArrayList<>();
+            methodPrefixRoles.put(prefix, rolesList);
+         }
+         for (String role : roles) {
+            rolesList.add(role);
+         }
+      }
+
+      public void addCatchAll(String... roles) {
+         for (String role : roles) {
+            catchAllRoles.add(role);
+         }
+      }
+
+      public String getDomain() {
+         return domain;
+      }
+
+      public List<String> getMatchingRolesForMethod(String methodName) {
+         List<String> roles = methodRoles.get(methodName);
+         if (roles != null) {
+            return roles;
+         }
+         for (Map.Entry<String, List<String>> entry : methodPrefixRoles.entrySet()) {
+            if (methodName.startsWith(entry.getKey())) {
+               return entry.getValue();
+            }
+         }
+         return catchAllRoles;
+      }
+   }
+   public static JMXAccessControlList createDefaultList() {
+      JMXAccessControlList accessControlList = new JMXAccessControlList();
+
+      accessControlList.addToWhiteList("hawtio", "type=*");
+
+      accessControlList.addToRoleAccess("org.apache.activemq.apache", null, "list*", "view", "update", "amq");
+      accessControlList.addToRoleAccess("org.apache.activemq.apache", null,"get*", "view", "update", "amq");
+      accessControlList.addToRoleAccess("org.apache.activemq.apache", null,"is*", "view", "update", "amq");
+      accessControlList.addToRoleAccess("org.apache.activemq.apache", null,"set*","update", "amq");
+      accessControlList.addToRoleAccess("org.apache.activemq.apache", null,"*", "amq");
+
+      accessControlList.addToDefaultAccess("list*", "view", "update", "amq");
+      accessControlList.addToDefaultAccess("get*", "view", "update", "amq");
+      accessControlList.addToDefaultAccess("is*", "view", "update", "amq");
+      accessControlList.addToDefaultAccess("set*", "update", "amq");
+      accessControlList.addToDefaultAccess("*", "amq");
+
+      return accessControlList;
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/62a2b14d/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/JaasAuthenticator.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/JaasAuthenticator.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/JaasAuthenticator.java
new file mode 100644
index 0000000..23167e9
--- /dev/null
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/management/JaasAuthenticator.java
@@ -0,0 +1,82 @@
+/*
+ * 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.core.server.management;
+
+import javax.management.remote.JMXAuthenticator;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import java.io.IOException;
+
+public class JaasAuthenticator implements JMXAuthenticator {
+
+   private String realm;
+
+   public String getRealm() {
+      return realm;
+   }
+
+   public void setRealm(String realm) {
+      this.realm = realm;
+   }
+
+   @Override
+   public Subject authenticate(Object credentials) throws SecurityException {
+      if (!(credentials instanceof String[])) {
+         throw new IllegalArgumentException("Expected String[2], got "
+               + (credentials != null ? credentials.getClass().getName() : null));
+      }
+
+      final String[] params = (String[]) credentials;
+      if (params.length != 2) {
+         throw new IllegalArgumentException("Expected String[2] but length was " + params.length);
+      }
+      try {
+         Subject subject = new Subject();
+         LoginContext loginContext = new LoginContext(realm, subject, new CallbackHandler() {
+
+            @Override
+            public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+               for (int i = 0; i < callbacks.length; i++) {
+                  if (callbacks[i] instanceof NameCallback) {
+                     ((NameCallback) callbacks[i]).setName(params[0]);
+                  } else if (callbacks[i] instanceof PasswordCallback) {
+                     ((PasswordCallback) callbacks[i]).setPassword((params[1].toCharArray()));
+                  } else {
+                     throw new UnsupportedCallbackException(callbacks[i]);
+                  }
+               }
+            }
+         });
+         loginContext.login();
+
+          /*  if (subject.getPrincipals().size() == 0) {
+                // there must be some Principals, but which ones required are tested later
+                throw new FailedLoginException("User does not have the required role");
+            }*/
+
+         return subject;
+      } catch (LoginException e) {
+         throw new SecurityException("Authentication failed", e);
+      }
+   }
+}


Mime
View raw message