Recently I was working with for a company to harden their set up of Active MQ. Though not the ultimate monitoring solution for Avtive MQ, they wanted to use the web console for providing some kind of ad hoc visibility on key properties. The ActiveMQ web page describes the set up that is pretty straight forward when an external servlet engine is used, but configuring the embedded jetty is a bit different.
From the
ActiveMQ web console documentation we could see that we need 3 things:
- An User Realm that can be plugged into the Jetty engine.
- Credentials definitions.
- A security aware web application.
Let's have a look at each of these things:
We start with rewriting the jetty bean definition in the default activemq.xml with the following activemq.xml:
<!-- 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. --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:amq="http://activemq.apache.org/schema/core" xmlns:jetty="http://mortbay.com/schemas/jetty/1.0" 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 http://activemq.apache.org/camel/schema/spring http://activemq.apache.org/camel/schema/spring/camel-spring.xsd"> <!-- Allows us to use system properties as variables in this configuration file --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>file:///${activemq.base}/conf/credentials.properties</value> </property> </bean> <broker xmlns="http://activemq.apache.org/schema/core" brokerName="TRT_INT" dataDirectory="${activemq.base}/data"> <!-- Destination specific policies using destination names or wildcards --> <destinationPolicy> <policyMap> <policyEntries> <policyEntry queue=">" producerFlowControl="true"/> <policyEntry topic=">" producerFlowControl="true"/> </policyEntries> </policyMap> </destinationPolicy> <!-- Define Virtual Destinations for Topics --> <!-- All topics will have a corresponding queue corresponding to the name pattern below where consumers can connect to in order to act as subscription groups. --> <destinationInterceptors> <virtualDestinationInterceptor> <virtualDestinations> <virtualTopic name=">" prefix="VTopic.*." /> </virtualDestinations> </virtualDestinationInterceptor> </destinationInterceptors> <!-- predefine Queues corresponding to Virtual topics so that no messages get lost due to unregistered consumers. --> <destinations> <!-- The Subscriber group App1 is the name of a queue that ALL instances of App1 would use to consume messages from the topic "X". All consumers using the same queue name act as ONE subscriber and the messages will be load balanced across the group. --> <!-- queue physicalName="VTopic.App1.X" / --> </destinations> <!-- Use the following to configure how ActiveMQ is exposed in JMX --> <managementContext> <managementContext createConnector="true"/> </managementContext> <!-- The store and forward broker networks ActiveMQ will listen to --> <networkConnectors> <!-- by default just auto discover the other brokers --> <!--<networkConnector name="default-nc" uri="multicast://default"/>--> <!-- Example of a static configuration: <networkConnector name="host1 and host2" uri="static://(tcp://host1:61616,tcp://host2:61616)"/> --> </networkConnectors> <!-- Using the Kaha DB store for persistence now --> <persistenceAdapter> <kahaDB directory="${activemq.base}/data/kahadb" /> </persistenceAdapter> <!-- Don't have ssl <sslContext> <sslContext keyStore="file:${activemq.base}/conf/broker.ks" keyStorePassword="password" trustStore="file:${activemq.base}/conf/broker.ts" trustStorePassword="password"/> </sslContext --> <!-- The maximum about of space the broker will use before slowing down producers --> <systemUsage> <systemUsage> <memoryUsage> <memoryUsage limit="350 mb"/> </memoryUsage> <storeUsage> <storeUsage limit="20 gb" name="foo"/> <!-- used for persistent messages --> </storeUsage> <tempUsage> <tempUsage limit="100 mb"/> <!-- used for non persistent messages --> </tempUsage> </systemUsage> </systemUsage> <!-- The transport connectors ActiveMQ will listen to --> <transportConnectors> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616"/> </transportConnectors> </broker> <jetty:jetty> <connectors> <jetty:nioConnector port="8161"/> </connectors> <handlers> <jetty:webAppContext contextPath="/admin" resourceBase="${activemq.base}/webapps/admin" logUrlOnStart="true"/> </handlers> <userRealms> <bean class="org.mortbay.jetty.security.HashUserRealm"> <property name="name" value="ActiveMQ Realm" /> <property name="config" value="${activemq.base}/conf/webconsole.properties" /> </bean> </userRealms> </jetty:jetty> </beans>
|
Next you need to create the file webconsole.properties in the conf directory of ActiveMQ.The file contains one line per user with the format
useName: password, [roleName]*
|
For example:
myAdmin: THESECRET, amqAdmin
|
Finally you need to amend the web.xml files of the ActiveMQ web applications (${activemq.base}/webapps/*/WEB-INF/web.xml) with the following xml fragment:
<security-constraint> <web-resource-collection> <web-resource-name>A Protected Page</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>amqAdminrole-name> </auth-constraint> </security-constraint>
<login-config> <auth-method>BASIC</auth-method> <realm-name>ActiveMQ Realm</realm-name> </login-config>
|
Make sure, the Realm name matches the one you have set in the Realm definition and the role name match roles you have named in the properties file.
5 comments:
Your post is just what i was looking for. Could you post your full activemq.xml? I'm having trouble with xml namespaces and could use further help,
Thanks
!
James,
sorry to react late, but my blog didnt notify me of your message.
I have updated the post with a working version. You were right about the namespaces.
Best regards
Andreas
Thank you very much for this helpful post.
This is great and helpful post. Thank you.
Cybergraphix
Post a Comment