Skip to content

Toro Cloud Dev Center


Remote ActiveMQ authentication and authorization

Haven't set up your remote ActiveMQ instance yet?

Read TORO's page on configuring a remote ActiveMQ instance to see the step-by-step procedures required to successfully deploy a stand-alone version of ActiveMQ and connect it to Martini.

Oftentimes, access to the message broker and its destinations must be restricted in order to prevent unwarranted incidences like the unauthorized deletion of data. Luckily, ActiveMQ provides "flexible and customizable security models"1 which make integrating with existing environment security policies easier.

Security in ActiveMQ is pluggable and achieved through the use of plugins from providers; two of the most common of which are the JAAS plugin and the simple authentication plugin2. The simple authentication plugin, as its name implies, may help you fulfill your authentication requirements. The JAAS plugin, on the other hand, allows you to manage users and groups without having to modify the broker.xml file directly (which is required for the simple authentication plugin).

In this guide, you will see how to set-up a remote ActiveMQ instance's authentication and authorization mechanisms through the aforementioned plugins. There are many other plugins you can use to configure your ActiveMQ instance's security; but at the moment, this is what TORO recommends for those who want to use remote ActiveMQ with Martini.

Authentication and authorization

Authentication is the process by which the user or system proves its identity to the server or client. This is typically done through the use of username-password combinations and other similar methods like one-time passwords sent to verified devices. Authentication does not determine the capabilities of the user; it only identifies and verifies the user or system requesting access.

Authorization, on the other hand, is the process that determines the privileges of the user or system on a secured resource. It works hand in hand with authentication.

Configuring the ActiveMQ server

The security settings of your ActiveMQ instance should depend on how your organization uses the broker. The procedures below will help you create a simple security configuration for your server using the JAAS authentication plugin and the authorization plugin; modify settings as needed.

  1. Go to ActiveMQ's configuration directory.

    1
    cd $activemq_home/conf
    
  2. Open the activemq.xml file and declare the runtimeConfigurationPlugin and the jaasAuthenticationPlugin. The runtimeConfigurationPlugin will enable modified broker settings to be applied on-the-go while the jaasAuthenticationPlugin will allow log-ins based on JMS username-password credentials sent by clients.

    1
    2
    3
    4
    <plugins>
        <runtimeConfigurationPlugin checkPeriod="1000" />
        <jaasAuthenticationPlugin configuration="activemq-domain" />
    </plugins>
    

    You may add this bit just underneath the <managementContext> ... </managementContext> section. Save and close the file.

    runtimeConfigurationPlugin

    This plugin is in charge of monitoring and applying changes from the broker.xml file to the running broker.

  3. Define the JAAS realm.

    Simply put, a realm is a 'database' of credentials, identifying the valid users of an application and their roles3.

    In this example, a login.config file will contain the snippet above, which will enable you to make use of Java property files to define users and groups.

    Reload

    The reload attribute which is now set to true will work with the runtimeConfigurationPlugin set earlier to give the broker the privilege to update broker settings on-the-fly.

    Save your configuration once done.

  4. Create and populate the Java property files specified in the preceding step. In this case, these files are named users.properties and groups.properties.

    users.properties, as its name implies, will contain the list of users and their passwords, declared using the format:

    1
    username=password
    

    groups.properties, on the other hand, will contain the list of groups and the users belonging to them. Groups will be declared using the format:

    1
    groupname=user_one,user_two,...
    
  5. Configure authorizationPlugin and define access privileges.

    Use <authorizationEntry /> elements to specify access privileges of previously defined groups for every destination (queue or topic). By entering the name of a group in a read attribute, you allow this group to browse and consume from the destination; write allows the sending of messages; and admin for the ability to create non-existent destinations lazily.

    For example:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    <plugins>
        <!-- ... -->
        <authorizationPlugin>
        <map>
            <authorizationMap>
                <authorizationEntries>
                    <authorizationEntry topic="jmsPrefix.statistics.>" read="$yourGroup" write="$yourGroup" admin="$yourGroup" />
                    <authorizationEntry topic="jmsPrefix.io.toro.martini.>" read="$yourGroup" write="$yourGroup" admin="$yourGroup" />
                    <authorizationEntry queue="jmsPrefix.io.toro.martini.>" read="$yourGroup" write="$yourGroup" admin="$yourGroup" />
                    <authorizationEntry topic="ActiveMQ.Advisory.>" read="$yourGroup" write="$yourGroup" admin="$yourGroup" />
                </authorizationEntries>
            </authorizationMap>
        </map>
        </authorizationPlugin>
    </plugins>
    

    Wildcards

    Use . to separate names in a path and create destination hierarchies; * to match any name in a path; and > to select destinations that match the path defined before the symbol.

    Authorization entry that affects all destinations?

    To create an entry that applies to all topics, the application needs be to configured to have a unique identifier that is prefixed on all of its topics; thereby making it easier to create an entry that matches all destinations using wildcards.

    jmsPrefix?

    jms.destination-prefix is a Martini-specific property that is used to prevent destination name collisions. This property is relevant especially when managing multiple Martini instances. The jmsPrefix path in the example authorizationEntrys above is a modifiable value set via your Martini instance's application properties.

  6. Restart ActiveMQ.

    1. Go to the $activemq_home/bin directory.
    2. Run ActiveMQ on a separate terminal, using either the start (for Windows) or console (for Unix) command. This will allow you to check through ActiveMQ's logs easily.

      1
      2
      $activemq_home\bin\activemq start # Windows
      $activemq_home/bin/activemq console #macOS/Linux
      
  7. Verify if your new security configurations were applied. Your activemq.xml file should now roughly look like:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <broker>
       <!-- ... -->
       <managementContext>
           <managementContext createConnector="false"/>
       </managementContext>
    
       <plugins>
           <jaasAuthenticationPlugin configuration="activemq-domain" />
           <runtimeConfigurationPlugin checkPeriod="1000" />
       <authorizationPlugin>
       <map>
           <authorizationMap>
               <authorizationEntries>
                   <authorizationEntry topic="jmsPrefix.statistics.>" read="admins" write="admins" admin="admins" />
                   <authorizationEntry topic="jmsPrefix.io.toro.martini.>" read="admins" write="admins" admin="admins" />
                   <authorizationEntry queue="jmsPrefix.io.toro.martini.>" read="admins" write="admins" admin="admins" />
                   <authorizationEntry topic="ActiveMQ.Advisory.>" read="admins" write="admins" admin="admins" />
               </authorizationEntries>
           </authorizationMap>
       </map>
       </authorizationPlugin>
       </plugins>
       <!-- ... -->
    </broker>
    

Configuring Martini

To let Martini connect to the remote ActiveMQ instance after updating its security policies, you must now edit its application.properties.

Write your configurations in override.properties instead of application.properties

The application.properties file contains the default configuration settings of Martini. Instead of directly editing this file and overwriting the default configuration, Martini allows developers to create an override.properties file. This file takes priority over the application.properties file, overriding properties already present there; effectively allowing you to retain the default configuration while being able to customize it using a different file.

The steps below describe how to edit the override.properties file directly.

  1. Go to Martini's conf/properties directly.

    1
    cd <martini-home>/conf/properties
    
  2. Open and edit the override.properties4 file.

    1. Set the activemq.username and activemq.password properties' values so that it contains the credentials necessary to connect to your remote ActiveMQ instance.

      1
      2
      activemq.username=admin
      activemq.password=admin
      
    2. Edit the required jms.* properties so that Martini knows the parameters required to connect to the ActiveMQ server.

      1
      2
      3
      4
      jms.configuration-file=activemq-external
      jms.client-id=martini
      activemq.uri=tcp://<activemq-ip-address>:61616?closeAsync=true
      jms.destination-prefix=your-prefix
      

      Value for jms.destination-prefix

      It is recommended that you make the prefix match the username entered earlier in the users.properties file to easily track and refer to the topics and resources that will be generated by ActiveMQ.

  3. Restart your Martini instance to reflect the changes you've made. Check logs if necessary.

  4. Login to ActiveMQ and check if the topics were digested by the broker.

    1. Access and login as the administrator to ActiveMQ's web console.
    2. Go to the Topic panel to check.

  1. Snyder, Bosanac, and Davies. (2011). ActiveMQ in Action. Retrieved from Safari Books Online database. 

  2. Apache ActiveMQ. (n.d.). Apache ActiveMQ ™ -- Security. Retrieved January 4, 2019, from http://activemq.apache.org/security.html 

  3. Apache Tomcat. (n.d.). Realm Configuration HOW-TO. Retrieved January 6, 2019, from https://tomcat.apache.org/tomcat-8.0-doc/realm-howto.html#What_is_a_Realm

  4. Instead of override.properties, you can use a .properties file whose name or location differs using the integrate.override.properties property.