You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by gt...@apache.org on 2013/11/05 21:45:43 UTC
git commit: https://issues.apache.org/jira/browse/AMQ-4849 - runtime
modifications to simpleAuthenticationPlugin plugin implemented with test
Updated Branches:
refs/heads/trunk 4367ec1b8 -> 67a7d30b4
https://issues.apache.org/jira/browse/AMQ-4849 - runtime modifications to simpleAuthenticationPlugin plugin implemented with test
Project: http://git-wip-us.apache.org/repos/asf/activemq/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/67a7d30b
Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/67a7d30b
Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/67a7d30b
Branch: refs/heads/trunk
Commit: 67a7d30b4702647a8b51758e61aa628618f42fa9
Parents: 4367ec1
Author: gtully <ga...@gmail.com>
Authored: Tue Nov 5 20:37:31 2013 +0000
Committer: gtully <ga...@gmail.com>
Committed: Tue Nov 5 20:38:23 2013 +0000
----------------------------------------------------------------------
.../activemq/security/AuthenticationUser.java | 3 +
.../security/SimpleAuthenticationBroker.java | 12 ++-
.../security/SimpleAuthenticationPlugin.java | 12 +++
.../plugin/RuntimeConfigurationBroker.java | 83 ++++++++++++++++----
.../src/main/resources/binding.xjb | 8 ++
.../org/apache/activemq/AuthenticationTest.java | 71 +++++++++++++++++
.../activemq/authenticationTest-two-users.xml | 59 ++++++++++++++
.../activemq/authenticationTest-users.xml | 54 +++++++++++++
8 files changed, 286 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/activemq/blob/67a7d30b/activemq-broker/src/main/java/org/apache/activemq/security/AuthenticationUser.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/security/AuthenticationUser.java b/activemq-broker/src/main/java/org/apache/activemq/security/AuthenticationUser.java
index edd0eab..65d34d5 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/security/AuthenticationUser.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/security/AuthenticationUser.java
@@ -28,6 +28,9 @@ public class AuthenticationUser {
String password;
String groups;
+ public AuthenticationUser() {
+ }
+
public AuthenticationUser(String username, String password, String groups) {
this.username = username;
this.password = password;
http://git-wip-us.apache.org/repos/asf/activemq/blob/67a7d30b/activemq-broker/src/main/java/org/apache/activemq/security/SimpleAuthenticationBroker.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/security/SimpleAuthenticationBroker.java b/activemq-broker/src/main/java/org/apache/activemq/security/SimpleAuthenticationBroker.java
index 6e61e88..46544f7 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/security/SimpleAuthenticationBroker.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/security/SimpleAuthenticationBroker.java
@@ -34,8 +34,8 @@ public class SimpleAuthenticationBroker extends AbstractAuthenticationBroker {
private boolean anonymousAccessAllowed = false;
private String anonymousUser;
private String anonymousGroup;
- private final Map<String,String> userPasswords;
- private final Map<String,Set<Principal>> userGroups;
+ private Map<String,String> userPasswords;
+ private Map<String,Set<Principal>> userGroups;
public SimpleAuthenticationBroker(Broker next, Map<String,String> userPasswords, Map<String,Set<Principal>> userGroups) {
super(next);
@@ -55,6 +55,14 @@ public class SimpleAuthenticationBroker extends AbstractAuthenticationBroker {
this.anonymousGroup = anonymousGroup;
}
+ public void setUserPasswords(Map<String,String> value) {
+ userPasswords = value;
+ }
+
+ public void setUserGroups(Map<String, Set<Principal>> value) {
+ userGroups = value;
+ }
+
@Override
public void addConnection(ConnectionContext context, ConnectionInfo info) throws Exception {
http://git-wip-us.apache.org/repos/asf/activemq/blob/67a7d30b/activemq-broker/src/main/java/org/apache/activemq/security/SimpleAuthenticationPlugin.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/security/SimpleAuthenticationPlugin.java b/activemq-broker/src/main/java/org/apache/activemq/security/SimpleAuthenticationPlugin.java
index 7d518ea..a334a98 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/security/SimpleAuthenticationPlugin.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/security/SimpleAuthenticationPlugin.java
@@ -93,14 +93,26 @@ public class SimpleAuthenticationPlugin implements BrokerPlugin {
this.anonymousAccessAllowed = anonymousAccessAllowed;
}
+ public boolean isAnonymousAccessAllowed() {
+ return anonymousAccessAllowed;
+ }
+
public void setAnonymousUser(String anonymousUser) {
this.anonymousUser = anonymousUser;
}
+ public String getAnonymousUser() {
+ return anonymousUser;
+ }
+
public void setAnonymousGroup(String anonymousGroup) {
this.anonymousGroup = anonymousGroup;
}
+ public String getAnonymousGroup() {
+ return anonymousGroup;
+ }
+
/**
* Sets the groups a user is in. The key is the user name and the value is a
* Set of groups
http://git-wip-us.apache.org/repos/asf/activemq/blob/67a7d30b/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java
----------------------------------------------------------------------
diff --git a/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java b/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java
index 0d08faf..ce26534 100644
--- a/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java
+++ b/activemq-runtime-config/src/main/java/org/apache/activemq/plugin/RuntimeConfigurationBroker.java
@@ -17,7 +17,6 @@
package org.apache.activemq.plugin;
import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.util.ArrayList;
@@ -69,10 +68,12 @@ import org.apache.activemq.broker.region.virtual.VirtualTopic;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
+import org.apache.activemq.command.ConnectionInfo;
import org.apache.activemq.filter.DestinationMapEntry;
import org.apache.activemq.network.DiscoveryNetworkConnector;
import org.apache.activemq.network.NetworkConnector;
import org.apache.activemq.plugin.jmx.RuntimeConfigurationView;
+import org.apache.activemq.schema.core.DtoAuthenticationUser;
import org.apache.activemq.schema.core.DtoAuthorizationEntry;
import org.apache.activemq.schema.core.DtoAuthorizationMap;
import org.apache.activemq.schema.core.DtoAuthorizationPlugin;
@@ -83,11 +84,15 @@ import org.apache.activemq.schema.core.DtoNetworkConnector;
import org.apache.activemq.schema.core.DtoPolicyEntry;
import org.apache.activemq.schema.core.DtoPolicyMap;
import org.apache.activemq.schema.core.DtoQueue;
+import org.apache.activemq.schema.core.DtoSimpleAuthenticationPlugin;
import org.apache.activemq.schema.core.DtoTopic;
import org.apache.activemq.schema.core.DtoVirtualDestinationInterceptor;
import org.apache.activemq.schema.core.DtoVirtualTopic;
+import org.apache.activemq.security.AuthenticationUser;
import org.apache.activemq.security.AuthorizationBroker;
import org.apache.activemq.security.AuthorizationMap;
+import org.apache.activemq.security.SimpleAuthenticationBroker;
+import org.apache.activemq.security.SimpleAuthenticationPlugin;
import org.apache.activemq.security.TempDestinationAuthorizationEntry;
import org.apache.activemq.security.XBeanAuthorizationEntry;
import org.apache.activemq.security.XBeanAuthorizationMap;
@@ -95,9 +100,7 @@ import org.apache.activemq.spring.Utils;
import org.apache.activemq.util.IntrospectionSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.xml.PluggableSchemaResolver;
import org.springframework.core.io.Resource;
import org.w3c.dom.Document;
@@ -112,13 +115,15 @@ public class RuntimeConfigurationBroker extends BrokerFilter {
public static final Logger LOG = LoggerFactory.getLogger(RuntimeConfigurationBroker.class);
public static final String objectNamePropsAppendage = ",service=RuntimeConfiguration,name=Plugin";
private final ReentrantReadWriteLock addDestinationBarrier = new ReentrantReadWriteLock();
+ private final ReentrantReadWriteLock addConnectionBarrier = new ReentrantReadWriteLock();
PropertiesPlaceHolderUtil placeHolderUtil = null;
private long checkPeriod;
private long lastModified = -1;
private Resource configToMonitor;
private DtoBroker currentConfiguration;
private Runnable monitorTask;
- private ConcurrentLinkedQueue<Runnable> destinationInterceptorUpdateWork = new ConcurrentLinkedQueue<Runnable>();
+ private ConcurrentLinkedQueue<Runnable> addDestinationWork = new ConcurrentLinkedQueue<Runnable>();
+ private ConcurrentLinkedQueue<Runnable> addConnectionWork = new ConcurrentLinkedQueue<Runnable>();
private ObjectName objectName;
private String infoString;
private Schema schema;
@@ -184,13 +189,13 @@ public class RuntimeConfigurationBroker extends BrokerFilter {
// modification to virtual destinations interceptor needs exclusive access to destination add
@Override
public Destination addDestination(ConnectionContext context, ActiveMQDestination destination, boolean createIfTemporary) throws Exception {
- Runnable work = destinationInterceptorUpdateWork.poll();
+ Runnable work = addDestinationWork.poll();
if (work != null) {
try {
addDestinationBarrier.writeLock().lockInterruptibly();
do {
work.run();
- work = destinationInterceptorUpdateWork.poll();
+ work = addDestinationWork.poll();
} while (work != null);
return super.addDestination(context, destination, createIfTemporary);
} finally {
@@ -206,6 +211,31 @@ public class RuntimeConfigurationBroker extends BrokerFilter {
}
}
+ // modification to authentication plugin needs exclusive access to connection add
+ @Override
+ public void addConnection(ConnectionContext context, ConnectionInfo info) throws Exception {
+ Runnable work = addConnectionWork.poll();
+ if (work != null) {
+ try {
+ addConnectionBarrier.writeLock().lockInterruptibly();
+ do {
+ work.run();
+ work = addConnectionWork.poll();
+ } while (work != null);
+ super.addConnection(context, info);
+ } finally {
+ addConnectionBarrier.writeLock().unlock();
+ }
+ } else {
+ try {
+ addConnectionBarrier.readLock().lockInterruptibly();
+ super.addConnection(context, info);
+ } finally {
+ addConnectionBarrier.readLock().unlock();
+ }
+ }
+ }
+
public String updateNow() {
LOG.info("Manual configuration update triggered");
infoString = "";
@@ -235,7 +265,7 @@ public class RuntimeConfigurationBroker extends BrokerFilter {
}
private void info(String s) {
- LOG.info(s);
+ LOG.info(filterPasswords(s));
if (infoString != null) {
infoString += s;
infoString += ";";
@@ -243,7 +273,7 @@ public class RuntimeConfigurationBroker extends BrokerFilter {
}
private void info(String s, Throwable t) {
- LOG.info(s, t);
+ LOG.info(filterPasswords(s), t);
if (infoString != null) {
infoString += s;
infoString += ", " + t;
@@ -255,8 +285,8 @@ public class RuntimeConfigurationBroker extends BrokerFilter {
DtoBroker changed = loadConfiguration(configToMonitor);
if (changed != null && !currentConfiguration.equals(changed)) {
LOG.info("change in " + configToMonitor + " at: " + new Date(lastModified));
- LOG.debug("current:" + currentConfiguration);
- LOG.debug("new :" + changed);
+ LOG.debug("current:" + filterPasswords(currentConfiguration));
+ LOG.debug("new :" + filterPasswords(changed));
processSelectiveChanges(currentConfiguration, changed);
currentConfiguration = changed;
} else {
@@ -320,7 +350,7 @@ public class RuntimeConfigurationBroker extends BrokerFilter {
answer.add(val);
}
} catch (NoSuchMethodException mappingIncomplete) {
- LOG.debug(o + " has no modifiable elements");
+ LOG.debug(filterPasswords(o) + " has no modifiable elements");
} catch (Exception e) {
info("Failed to access getContents for " + o + ", runtime modifications not supported", e);
}
@@ -360,6 +390,24 @@ public class RuntimeConfigurationBroker extends BrokerFilter {
info("failed to apply modified AuthorizationMap to AuthorizationBroker", e);
}
+ } else if (candidate instanceof DtoSimpleAuthenticationPlugin) {
+ try {
+ final SimpleAuthenticationPlugin updatedPlugin = fromDto(candidate, new SimpleAuthenticationPlugin());
+ final SimpleAuthenticationBroker authenticationBroker =
+ (SimpleAuthenticationBroker) getBrokerService().getBroker().getAdaptor(SimpleAuthenticationBroker.class);
+ addConnectionWork.add(new Runnable() {
+ public void run() {
+ authenticationBroker.setUserGroups(updatedPlugin.getUserGroups());
+ authenticationBroker.setUserPasswords(updatedPlugin.getUserPasswords());
+ authenticationBroker.setAnonymousAccessAllowed(updatedPlugin.isAnonymousAccessAllowed());
+ authenticationBroker.setAnonymousUser(updatedPlugin.getAnonymousUser());
+ authenticationBroker.setAnonymousGroup(updatedPlugin.getAnonymousGroup());
+ }
+ });
+ } catch (Exception e) {
+ info("failed to apply SimpleAuthenticationPlugin modifications to SimpleAuthenticationBroker", e);
+ }
+
} else if (candidate instanceof DtoPolicyMap) {
List<Object> existingEntries = filter(existing, DtoPolicyMap.PolicyEntries.class);
@@ -450,7 +498,7 @@ public class RuntimeConfigurationBroker extends BrokerFilter {
}
} else if (o instanceof DtoVirtualDestinationInterceptor) {
// whack it
- destinationInterceptorUpdateWork.add(new Runnable() {
+ addDestinationWork.add(new Runnable() {
public void run() {
List<DestinationInterceptor> interceptorsList = new ArrayList<DestinationInterceptor>();
for (DestinationInterceptor candidate : getBrokerService().getDestinationInterceptors()) {
@@ -500,7 +548,7 @@ public class RuntimeConfigurationBroker extends BrokerFilter {
}
} else if (o instanceof DtoVirtualDestinationInterceptor) {
final DtoVirtualDestinationInterceptor dto = (DtoVirtualDestinationInterceptor) o;
- destinationInterceptorUpdateWork.add(new Runnable() {
+ addDestinationWork.add(new Runnable() {
public void run() {
boolean updatedExistingInterceptor = false;
@@ -570,7 +618,7 @@ public class RuntimeConfigurationBroker extends BrokerFilter {
Properties properties = new Properties();
IntrospectionSupport.getProperties(dto, properties, null);
replacePlaceHolders(properties);
- LOG.trace("applying props: " + properties + ", to " + instance.getClass().getSimpleName());
+ LOG.trace("applying props: " + filterPasswords(properties) + ", to " + instance.getClass().getSimpleName());
IntrospectionSupport.setProperties(instance, properties);
// deal with nested elements
@@ -594,6 +642,11 @@ public class RuntimeConfigurationBroker extends BrokerFilter {
return instance;
}
+ Pattern matchPassword = Pattern.compile("password=.*,");
+ private String filterPasswords(Object toEscape) {
+ return matchPassword.matcher(toEscape.toString()).replaceAll("password=???,");
+ }
+
private Object matchType(List<Object> parameterValues, Class<?> aClass) {
Object result = parameterValues;
if (Set.class.isAssignableFrom(aClass)) {
@@ -607,6 +660,8 @@ public class RuntimeConfigurationBroker extends BrokerFilter {
return new ActiveMQTopic();
} else if (DtoQueue.class.isAssignableFrom(elementContent.getClass())) {
return new ActiveMQQueue();
+ } else if (DtoAuthenticationUser.class.isAssignableFrom(elementContent.getClass())) {
+ return new AuthenticationUser();
} else {
info("update not supported for dto: " + elementContent);
return new Object();
http://git-wip-us.apache.org/repos/asf/activemq/blob/67a7d30b/activemq-runtime-config/src/main/resources/binding.xjb
----------------------------------------------------------------------
diff --git a/activemq-runtime-config/src/main/resources/binding.xjb b/activemq-runtime-config/src/main/resources/binding.xjb
index 6e786a5..64b66ce 100644
--- a/activemq-runtime-config/src/main/resources/binding.xjb
+++ b/activemq-runtime-config/src/main/resources/binding.xjb
@@ -124,5 +124,13 @@
<jxb:property name="Contents" />
</jxb:bindings>
+ <jxb:bindings node="xs:element[@name='simpleAuthenticationPlugin']/xs:complexType/xs:choice">
+ <jxb:property name="Contents" />
+ </jxb:bindings>
+
+ <jxb:bindings node="xs:element[@name='simpleAuthenticationPlugin']/xs:complexType/xs:choice/xs:choice/xs:element[@name='users']/xs:complexType/xs:sequence">
+ <jxb:property name="Contents" />
+ </jxb:bindings>
+
</jxb:bindings>
</jxb:bindings>
http://git-wip-us.apache.org/repos/asf/activemq/blob/67a7d30b/activemq-runtime-config/src/test/java/org/apache/activemq/AuthenticationTest.java
----------------------------------------------------------------------
diff --git a/activemq-runtime-config/src/test/java/org/apache/activemq/AuthenticationTest.java b/activemq-runtime-config/src/test/java/org/apache/activemq/AuthenticationTest.java
new file mode 100644
index 0000000..eae6223
--- /dev/null
+++ b/activemq-runtime-config/src/test/java/org/apache/activemq/AuthenticationTest.java
@@ -0,0 +1,71 @@
+/**
+ * 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.
+ */
+package org.apache.activemq;
+
+import javax.jms.JMSException;
+import javax.jms.Session;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class AuthenticationTest extends RuntimeConfigTestSupport {
+
+ String configurationSeed = "authenticationTest";
+
+ @Test
+ public void testMod() throws Exception {
+ final String brokerConfig = configurationSeed + "-authentication-broker";
+ applyNewConfig(brokerConfig, configurationSeed + "-users");
+ startBroker(brokerConfig);
+ assertTrue("broker alive", brokerService.isStarted());
+
+ assertAllowed("test_user_password", "USERS.A");
+ assertDenied("another_test_user_password", "USERS.A");
+
+ // anonymous
+ assertDenied(null, "USERS.A");
+
+ applyNewConfig(brokerConfig, configurationSeed + "-two-users", SLEEP);
+
+ assertAllowed("test_user_password", "USERS.A");
+ assertAllowed("another_test_user_password", "USERS.A");
+ assertAllowed(null, "USERS.A");
+
+ }
+
+ private void assertDenied(String userPass, String destination) {
+ try {
+ assertAllowed(userPass, destination);
+ fail("Expected not allowed exception");
+ } catch (JMSException expected) {
+ LOG.debug("got:" + expected, expected);
+ }
+ }
+
+ private void assertAllowed(String userPass, String dest) throws JMSException {
+ ActiveMQConnection connection = new ActiveMQConnectionFactory("vm://localhost").createActiveMQConnection(userPass, userPass);
+ connection.start();
+ try {
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ session.createConsumer(session.createQueue(dest));
+ } finally {
+ connection.close();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq/blob/67a7d30b/activemq-runtime-config/src/test/resources/org/apache/activemq/authenticationTest-two-users.xml
----------------------------------------------------------------------
diff --git a/activemq-runtime-config/src/test/resources/org/apache/activemq/authenticationTest-two-users.xml b/activemq-runtime-config/src/test/resources/org/apache/activemq/authenticationTest-two-users.xml
new file mode 100644
index 0000000..9fa2c6a
--- /dev/null
+++ b/activemq-runtime-config/src/test/resources/org/apache/activemq/authenticationTest-two-users.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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: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" start="false" persistent="false">
+ <plugins>
+ <runtimeConfigurationPlugin checkPeriod="1000"/>
+
+ <simpleAuthenticationPlugin anonymousAccessAllowed="true" anonymousGroup="users" anonymousUser="au">
+ <users>
+ <authenticationUser groups="users" password="test_user_password" username="test_user_password"/>
+ <authenticationUser groups="users" password="another_test_user_password" username="another_test_user_password"/>
+ </users>
+ </simpleAuthenticationPlugin>
+
+ <!-- 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 topic=">" read="admins" write="admins" admin="admins"/>
+ <authorizationEntry topic="USERS.>" read="users" write="users" admin="users"/>
+
+ <authorizationEntry topic="ActiveMQ.Advisory.>" read="guests,users" write="guests,users"
+ admin="guests,users"/>
+ </authorizationEntries>
+
+ <tempDestinationAuthorizationEntry>
+ <tempDestinationAuthorizationEntry read="tempDestinationAdmins" write="tempDestinationAdmins"
+ admin="tempDestinationAdmins"/>
+ </tempDestinationAuthorizationEntry>
+ </authorizationMap>
+ </map>
+ </authorizationPlugin>
+ </plugins>
+ </broker>
+</beans>
http://git-wip-us.apache.org/repos/asf/activemq/blob/67a7d30b/activemq-runtime-config/src/test/resources/org/apache/activemq/authenticationTest-users.xml
----------------------------------------------------------------------
diff --git a/activemq-runtime-config/src/test/resources/org/apache/activemq/authenticationTest-users.xml b/activemq-runtime-config/src/test/resources/org/apache/activemq/authenticationTest-users.xml
new file mode 100644
index 0000000..9ed5535
--- /dev/null
+++ b/activemq-runtime-config/src/test/resources/org/apache/activemq/authenticationTest-users.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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: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" start="false" persistent="false">
+ <plugins>
+ <runtimeConfigurationPlugin checkPeriod="1000"/>
+
+ <simpleAuthenticationPlugin anonymousAccessAllowed="false" anonymousGroup="ag" anonymousUser="au"><users><authenticationUser groups="users" password="test_user_password" username="test_user_password"/></users></simpleAuthenticationPlugin>
+
+ <!-- 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 topic=">" read="admins" write="admins" admin="admins"/>
+ <authorizationEntry topic="USERS.>" read="users" write="users" admin="users"/>
+
+ <authorizationEntry topic="ActiveMQ.Advisory.>" read="guests,users" write="guests,users"
+ admin="guests,users"/>
+ </authorizationEntries>
+
+ <tempDestinationAuthorizationEntry>
+ <tempDestinationAuthorizationEntry read="tempDestinationAdmins" write="tempDestinationAdmins"
+ admin="tempDestinationAdmins"/>
+ </tempDestinationAuthorizationEntry>
+ </authorizationMap>
+ </map>
+ </authorizationPlugin>
+ </plugins>
+ </broker>
+</beans>