|
ActiveMQ 4.x provides pluggable security through various different providers. The most common providers are
Please note that the underlying examples use recent SNAPSHOTS, they will NOT work under the ActiveMQ 4.1.1 stable release. AuthenticationThe default JAAS Typically you configure JAAS using a config file like this one Authentication ExampleHere is an example login.config Simple Authentication PluginIf you have modest authentication requirements (or just want to quickly set up your testing environment) you can use SimpleAuthenticationPlugin. With this plugin you can define users and groups directly in the broker's XML configuration. Take a look at the following snippet for example: <simpleAuthenticationPlugin> <users> <authenticationUser username="system" password="manager" groups="users,admins"/> <authenticationUser username="user" password="password" groups="users"/> <authenticationUser username="guest" password="password" groups="guests"/> </users> </simpleAuthenticationPlugin> Users and groups defined in this way can be later used with the appropriate authorization plugin. AuthorizationIn ActiveMQ we use a number of operations which you can associate with user roles and either individual queues or topics or you can use wildcards to attach to hierarchies of topics and queues.
Queues/Topics can specified using the ActiveMQ wildcards syntax. Authorization ExampleThe following example <beans> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/> <broker useJmx="false" persistent="false" xmlns="http://activemq.apache.org/schema/core" populateJMSXUserID="true"> <plugins> <!-- use JAAS to authenticate using the login.config file on the classpath to configure JAAS --> <jaasAuthenticationPlugin configuration="activemq-domain" /> <!-- lets configure a destination based authorization mechanism --> <authorizationPlugin> <map> <authorizationMap> <authorizationEntries> <authorizationEntry queue=">" read="admins" write="admins" admin="admins" /> <authorizationEntry queue="USERS.>" read="users" write="users" admin="users" /> <authorizationEntry queue="GUEST.>" read="guests" write="guests,users" admin="guests,users" /> <authorizationEntry topic=">" read="admins" write="admins" admin="admins" /> <authorizationEntry topic="USERS.>" read="users" write="users" admin="users" /> <authorizationEntry topic="GUEST.>" read="guests" write="guests,users" admin="guests,users" /> <authorizationEntry topic="ActiveMQ.Advisory.>" read="guests,users" write="guests,users" admin="guests,users"/> </authorizationEntries> <!-- let's assign roles to temporary destinations. comment this entry if we don't want any roles assigned to temp destinations --> <tempDestinationAuthorizationEntry> <tempDestinationAuthorizationEntry read="tempDestinationAdmins" write="tempDestinationAdmins" admin="tempDestinationAdmins"/> </tempDestinationAuthorizationEntry> </authorizationMap> </map> </authorizationPlugin> </plugins> </broker> </beans> Broker-to-Broker Authentication and AuthorizationIf you have enabled authentication for a particular message broker, then other brokers that wish to connect to that broker must provide the proper authentication credentials via their <networkConnector> element. For example, suppose that we have a network of brokers with the following configuration:
In order for BrokerB to connect to BrokerA, the corresponding <networkConnector> element in BrokerB's XML configuration file must be set up as follows. <networkConnectors> <networkConnector name="brokerAbridge" userName="user" password="password" uri="static://(tcp://brokerA:61616)"/> </networkConnectors> Note how BrokerB's <networkConnector> element must provide the proper credentials in order to connect to BrokerA. If authorization has been enabled on BrokerA, then the userName assigned to the <networkConnector> element must also have the proper authorization credentials. Messages cannot be forwarded from BrokerB to BrokerA if BrokerA has authorization enabled and BrokerB's corresponding <networkConnector> element's userName has not been given the proper authorization credentials. Also, if BrokerA is given a <networkConnector> element so that it can initiate a connection to BrokerB, then that <networkConnector> must be given a userName/password combination that is defined in the <simpleAuthenticationPlugin> element; this is required even though BrokerB does not have authentication services enabled. Controlling Access To Temporary DestinationsTo control access to temporary destinations, you will need to add a <tempDestinationAuthorizationEntry> element to the authorizationMap. Through this element, you control access to all temporary destinations. If this element is not present, read, write, and admin privileges for temporary destinations will be granted to all. In the example below, read, write, and admin privileges for temporary destinations are only granted to those clients that have been assigned to the 'admin' group. <broker> .. <plugins> .. <authorizationPlugin> <map> <authorizationMap> <authorizationEntries> <authorizationEntry queue="TEST.Q" read="users" write="users" admin="users" /> <authorizationEntry topic="ActiveMQ.Advisory.>" read="all" write="all" admin="all"/> </authorizationEntries> <tempDestinationAuthorizationEntry> <tempDestinationAuthorizationEntry read="admin" write="admin" admin="admin"/> </tempDestinationAuthorizationEntry> </authorizationMap> </map> </authorizationPlugin> .. </plugins> .. </broker> Message level AuthorizationWe have a configurable MessageAuthorizationPolicy to allow you to authorize each message using some content based authorization policy of your choosing. To enable this policy configure on the broker directly using the * messageAuthorizationPolicy* property or add it to the XML as follows <broker> .. <messageAuthorizationPolicy> <bean class="com.acme.MyMessageAuthorizationPolicy" xmlns=""/> </messageAuthorizationPolicy> .. </broker> Implementing your own custom Security PluginAll of the various security implementations are implemented as Interceptors so its very easy to add your own custom implementation. Its probably easier to start with one of the simple implementations |