Search code examples
javajmxactivemq-artemis

Authorization by login / password does not work when connecting via JMX


I have a method whose parameters are passed values for connecting to the ActiveMQ Artemis broker via the JMX protocol. But my username/password is not working. That is, if I leave the user and password values empty, then it will still connect, and I want an error to pop up when connecting to the queue since the user data is incorrect

public static MBeanServerConnection connectBroker(String brokerUrl, String user, String password) {
    try {
        Map<String, String[]> env = new HashMap();
        String[] creds = {user, password};
        env.put(JMXConnector.CREDENTIALS, creds);
        JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + brokerUrl + ":13682/jmxrmi"), env);
        return connector.getMBeanServerConnection();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

It's strange that if CREDENTIALS is passed, it still works, but I want it to give an error if there is no such user

broker.xml:

<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">
        <name>localhost</name>
      <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>


      <!-- true to expose ActiveMQ Artemis resources through JMX -->
      <jmx-management-enabled>true</jmx-management-enabled>

      <!-- Acceptors -->
      <acceptors>
         <acceptor name="netty">tcp://localhost:61616</acceptor>
      </acceptors>

      <!-- Other config -->

      <security-settings>
         <!--security for example queue-->
         <security-setting match="exampleQueue">
            <permission roles="amq" type="createDurableQueue"/>
            <permission roles="amq" type="deleteDurableQueue"/>
            <permission roles="amq" type="createNonDurableQueue"/>
            <permission roles="amq" type="deleteNonDurableQueue"/>
            <permission roles="amq" type="consume"/>
            <permission roles="amq" type="send"/>
            <permission roles="amq" type="browse"/>
         </security-setting>
         <security-setting match="TestQueue">
            <permission roles="amq" type="createDurableQueue"/>
            <permission roles="amq" type="deleteDurableQueue"/>
            <permission roles="amq" type="createNonDurableQueue"/>
            <permission roles="amq" type="deleteNonDurableQueue"/>
            <permission roles="amq" type="consume"/>
            <permission roles="amq" type="send"/>
         </security-setting>
         <security-setting match="TestQueueSecond">
            <permission roles="amq" type="createDurableQueue"/>
            <permission roles="amq" type="deleteDurableQueue"/>
            <permission roles="amq" type="createNonDurableQueue"/>
            <permission roles="amq" type="deleteNonDurableQueue"/>
            <permission roles="amq" type="consume"/>
            <permission roles="amq" type="send"/>
         </security-setting>
      </security-settings>

      <addresses>
         <address name="exampleQueue">
            <anycast>
               <queue name="exampleQueue"/>
            </anycast>
         </address>
         <address name="TestQueue">
            <anycast>
               <queue name="TestQueue"/>
            </anycast>
         </address>
         <address name="TestQueueSecond">
            <anycast>
               <queue name="TestQueueSecond"/>
            </anycast>
         </address>
      </addresses>
   </core>
</configuration>

management.xml:

<management-context xmlns="http://activemq.apache.org/schema">
   <connector connector-port="13682" connector-host="localhost"/>
   <authorisation>
      <allowlist>
         <entry domain="hawtio"/>
      </allowlist>
      <default-access>
         <access method="list*" roles="view,update,amq,guest"/>
         <access method="get*" roles="view,update,amq,guest"/>
         <access method="is*" roles="view,update,amq,guest"/>
         <access method="set*" roles="update,amq,guest"/>
         <access method="*" roles="amq,guest"/>
      </default-access>
      <role-access>
         <match domain="org.apache.activemq.artemis">
            <access method="list*" roles="view,update,amq,guest"/>
            <access method="get*" roles="view,update,amq,guest"/>
            <access method="is*" roles="view,update,amq,guest"/>
            <access method="set*" roles="update,amq,guest"/>
            <access method="*" roles="amq,guest"/>
         </match>
         <!--example of how to configure a specific object-->
         <!--<match domain="org.apache.activemq.artemis" 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>

login.config:

activemq {
   org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule sufficient
       debug=false
       reload=true
       org.apache.activemq.jaas.properties.user="artemis-users.properties"
       org.apache.activemq.jaas.properties.role="artemis-roles.properties";
    
   org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient
       debug=false
       org.apache.activemq.jaas.guest.user="admin"
       org.apache.activemq.jaas.guest.role="amq";
};

Solution

  • Your login.config is using the GuestLoginModule, i.e.:

       org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient
           debug=false
           org.apache.activemq.jaas.guest.user="admin"
           org.apache.activemq.jaas.guest.role="amq";
    

    This means that users who don't pass any credentials or pass the wrong credentials will be accepted and given the username admin and the role amq. See the documentation for more details.

    If you don't want this behavior you can use this in your login.config instead:

    activemq {
       org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule required
           debug=false
           reload=true
           org.apache.activemq.jaas.properties.user="artemis-users.properties"
           org.apache.activemq.jaas.properties.role="artemis-roles.properties";
    };