ActiveMQ 5.10 and later provides a fully customizable security experience using Apache Shiro. The ActiveMQ Shiro plugin can secure the ActiveMQ broker, from authenticating transport connections to authorizing behavior with topics and queues and everything in between. QuickstartThe fastest/simplest way to enable the ShiroPlugin is to define it as a Spring bean in the <beans xmlns="http://www.springframework.org/schema/beans" xmlns:amq="http://activemq.apache.org/schema/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> <broker xmlns="http://activemq.apache.org/schema/core" ... other attributes here ...> <plugins> <bean id="shiroPlugin" class="org.apache.activemq.shiro.ShiroPlugin" xmlns="http://www.springframework.org/schema/beans"> <property name="iniConfig"><value> [main] # Shiro object graph configuration here if desired/necessary [users] # users section format: # # username = password [, assignedRole1, assignedRole2, ..., assignedRoleN] # # for example: # # scott = tiger, advisory, users, administrators # # Roles and permissions assigned to roles are defined in the [roles] section # below. By transitive association, any user assigned a role is granted the # role's permissions. # ActiveMQ System User # needed for in-VM/local connections when authentication is enabled: system = manager, system # Other users here. You should almost always add the `advisory` role for each # user to make your life easy! See the [roles] comments below for more info. # jsmith = jsmithsPassword, advisory # djones = djonesPassword, advisory, ... # etc. [roles] # roles section format: # # roleName = wildcardPermission1, wildcardPermission2, ..., wildcardPermissionN # # The 'system' role is assigned all permissions (*). Be careful when assigning # this to actual users other than then system user: system = * # Full access rights should generally be given to the ActiveMQ.Advisory.* # destinations because by default an ActiveMQConnection uses advisory topics to # get early knowledge of temp destination creation and deletion. For more info: # # http://activemq.apache.org/security.html # # So we create an 'advisory' role here with a wildcard/catch-all permissions # for all advisory topics. To make your life easy, ensure you assign this to # any/all users in the [users] section above, e.g. # # jsmith = jsmithsPassword, advisory, ... advisory = topic:ActiveMQ.Advisory* </value></property> </bean> </plugins> </broker> </beans> This config assumes you have a simple/small set of static users that access your ActiveMQ broker. We'll cover enabling more advanced user repositories later. Encrypted PasswordsThe above example uses plaintext passwords, which is simple to set up and easy to use for testing, but not really secure. Most production deployments will likely want to use encrypted passwords. For example: <bean id="shiroPlugin" class="org.apache.activemq.shiro.ShiroPlugin" xmlns="http://www.springframework.org/schema/beans"> <!-- enabled by default. To disable, uncomment: <property name="iniConfig"><value> [main] # Shiro object graph configuration here passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher iniRealm.credentialsMatcher = $passwordMatcher [users] scott = $shiro1$SHA-256$500000$eWpVX2tGX7WCP2J+jMCNqw==$it/NRclMOHrfOvhAEFZ0mxIZRdbcfqIBdwdwdDXW2dM=, advisory system = $shiro1$SHA-256$500000$eUyGwMGr9GYzB/gg/MoNgw==$WGc0yWFWv8+hLqjzVLgW7Hat2FQTywDXBl5izpqaLSY=, system [roles] system = * advisory = topic:ActiveMQ.Advisory* </value></property> </bean> As you can see, two things are different than the simpler/default configuration:
To get the hashed password text values, you will want to Download Shiro's Command Line Hasher from Maven Central. Once downloaded, you can use it to create secure password hashes that you can safely copy-and-paste in to the $ java -jar shiro-tools-hasher-X.X.X-cli.jar -p It will then ask you to enter the password and then confirm it: Password to hash: Password to hash (confirm): When this command executes, it will print out the securely-salted-iterated-and-hashed password. For example: $shiro1$SHA-256$500000$eWpVX2tGX7WCP2J+jMCNqw==$it/NRclMOHrfOvhAEFZ0mxIZRdbcfqIBdwdwdDXW2dM= Take this value and place it as the password in the user definition line (followed by any desired roles, such as the [users] scott = $shiro1$SHA-256$500000$eWpVX2tGX7WCP2J+jMCNqw==$it/NRclMOHrfOvhAEFZ0mxIZRdbcfqIBdwdwdDXW2dM=, advisory system = $shiro1$SHA-256$500000$eUyGwMGr9GYzB/gg/MoNgw==$WGc0yWFWv8+hLqjzVLgW7Hat2FQTywDXBl5izpqaLSY=, system ConfigurationThe ActiveMQ Shiro plugin can be configured in a number of ways. For example, with Java: BrokerService brokerService = new BrokerService(); ShiroPlugin shiroPlugin = new ShiroPlugin(); //configure shiroPlugin via getters/setters here broker.setPlugins(new BrokerPlugin[]{shiroPlugin}); //continue configuring the brokerService as necessary ... Or, if using traditional ActiveMQ xml, as a Spring bean in the <beans xmlns="http://www.springframework.org/schema/beans" xmlns:amq="http://activemq.apache.org/schema/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> <broker xmlns="http://activemq.apache.org/schema/core" ... other attributes here ...> <plugins> <bean id="shiroPlugin" class="org.apache.activemq.shiro.ShiroPlugin" xmlns="http://www.springframework.org/schema/beans"> <!-- Config properties via getters/setters as necessary: --> </bean> </plugins> </broker> </beans> The remaining configuration examples on this page will be shown as bean XML, but know that the same configuration can be done in Java as standard JavaBeans-compatible getter and setter methods. Enabling/DisablingYou can enable or disable the ShiroPlugin entirely without having to remove it from your configuration. This is convenient when testing, or when you want to enable or disable it based on a configuration parameter at startup. <bean id="shiroPlugin" class="org.apache.activemq.shiro.ShiroPlugin" xmlns="http://www.springframework.org/schema/beans"> <!-- enabled by default. To disable, uncomment: <property name="enabled" value="false"/> --> </bean> A nice technique is to use Spring's PropertySourcesPlaceholderConfigurer and placeholder tokens (set <beans ...> <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> ... </bean> <broker ...> <plugins ...> <bean id="shiroPlugin" class="org.apache.activemq.shiro.ShiroPlugin" xmlns="http://www.springframework.org/schema/beans"> <property name="enabled" value="${shiro.enabled}"/> </bean> </plugins> </broker> </beans> This allows you to enable or disable the Shiro plugin by simply setting a property in a Shiro EnvironmentThe
Custom EnvironmentA Shiro <beans ...> <broker ...> <plugins> <bean id="shiroPlugin" class="org.apache.activemq.shiro.ShiroPlugin" xmlns="http://www.springframework.org/schema/beans"> <property name="environment" ref="shiroEnvironment"/> </bean> </plugins> </broker> <bean id="shiroEnvironment" class=".."> ... config here ... </bean> <bean class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> </beans> Custom SecurityManagerInstead of configuring an <beans ...> <broker ...> <plugins> <bean id="shiroPlugin" class="org.apache.activemq.shiro.ShiroPlugin" xmlns="http://www.springframework.org/schema/beans"> <property name="securityManager" ref="shiroSecurityManager"/> </bean> </plugins> </broker> <bean id="shiroSecurityManager" class="org.apache.shiro.mgt.DefaultSecurityManager"> <property name="realms"> <list> <bean id="myRealm" class="..."> ... </bean> ... maybe more Realm beans ... </list> </property> </bean> <bean class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> </beans> If specifying a shiro.ini FileIf you don't want to construct a <beans ...> <broker ...> <plugins> <bean id="shiroPlugin" class="org.apache.activemq.shiro.ShiroPlugin" xmlns="http://www.springframework.org/schema/beans"> <property name="iniResourcePath" value="classpath:myshiro.ini"/> </bean> </plugins> </broker> </beans> This allows you to keep your Shiro config separate from your ActiveMQ broker configuration if you prefer. shiro.ini EmbeddedIf you want to use ini configuration and you would prefer to have all configuration in one place, you can embed the ini config instead: <beans ...> <broker ...> <plugins ...> <bean id="shiroPlugin" class="org.apache.activemq.shiro.ShiroPlugin" xmlns="http://www.springframework.org/schema/beans"> <property name="iniConfig"> <value> [main] # Shiro object graph configuration here if desired/necessary [users] system = manager, system [roles] system = * advisory = topic:ActiveMQ.Advisory* </value> </property> </bean> </plugins> </broker> </beans> DesignThe Shiro plugin is a BrokerPlugin that inserts 3 BrokerFilters in the broker filter chain: the SubjectFilter The AuthenticationFilter The AuthorizationFilter The For example, it would ensure that the SubjectFilterThe ShiroPlugin installs and executes the The
Unless you're deeply familiar with ActiveMQ's security model, you can safely skip to Authentication below. ConnectionSubjectFactoryA Most However, if there is some other data associated with the connection that can be inspected to create a Subject instance beyond what the <bean id="shiroPlugin" class="org.apache.activemq.shiro.ShiroPlugin" xmlns="http://www.springframework.org/schema/beans"> <property name="subjectFilter.connectionSubjectFactory"> <bean class="com.my.ConnectionSubjectFactory" .../> </property> </bean> SecurityContextFactoryThe ActiveMQ The <bean id="shiroPlugin" class="org.apache.activemq.shiro.ShiroPlugin" xmlns="http://www.springframework.org/schema/beans"> <property name="subjectFilter.securityContextFactory"> <bean class="com.my.SecurityContextFactory" .../> </property> </bean> Note however that much of the plugin's functionality and downstream filters expect created AuthenticationThe ShiroPlugin installs the WORK IN PROGRESS - STILL AUTHORING |