diff --git a/activemq-core/src/main/java/org/apache/activemq/broker/BrokerPlugin.java b/activemq-core/src/main/java/org/apache/activemq/broker/BrokerPlugin.java new file mode 100644 index 0000000000..fe67e3cdab --- /dev/null +++ b/activemq-core/src/main/java/org/apache/activemq/broker/BrokerPlugin.java @@ -0,0 +1,32 @@ +/** + * + * Copyright 2005-2006 The Apache Software Foundation + * + * Licensed 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.broker; + +/** + * Represents a plugin into a Broker + * + * @version $Revision$ + */ +public interface BrokerPlugin { + + /** + * Installs the plugin into the interceptor chain of the broker, returning the new + * intercepted broker to use. + */ + public Broker installPlugin(Broker broker); + +} diff --git a/activemq-core/src/main/java/org/apache/activemq/broker/BrokerService.java b/activemq-core/src/main/java/org/apache/activemq/broker/BrokerService.java index 341eff660e..4ccbc8848a 100644 --- a/activemq-core/src/main/java/org/apache/activemq/broker/BrokerService.java +++ b/activemq-core/src/main/java/org/apache/activemq/broker/BrokerService.java @@ -112,6 +112,7 @@ public class BrokerService implements Service { private URI vmConnectorURI; private PolicyMap destinationPolicy; private AtomicBoolean started = new AtomicBoolean(false); + private BrokerPlugin[] plugins; /** * Adds a new transport connector for the given bind address @@ -677,6 +678,17 @@ public class BrokerService implements Service { this.destinationPolicy = policyMap; } + public BrokerPlugin[] getPlugins() { + return plugins; + } + + /** + * Sets a number of broker plugins to install such as for security authentication or authorization + */ + public void setPlugins(BrokerPlugin[] plugins) { + this.plugins = plugins; + } + // Implementation methods // ------------------------------------------------------------------------- /** @@ -876,6 +888,12 @@ public class BrokerService implements Service { if (isPopulateJMSXUserID()) { broker = new UserIDBroker(broker); } + if (plugins != null) { + for (int i = 0; i < plugins.length; i++) { + BrokerPlugin plugin = plugins[i]; + broker = plugin.installPlugin(broker); + } + } return broker; } diff --git a/activemq-core/src/main/java/org/apache/activemq/security/JassAuthenticationPlugin.java b/activemq-core/src/main/java/org/apache/activemq/security/JassAuthenticationPlugin.java new file mode 100644 index 0000000000..a1a006220f --- /dev/null +++ b/activemq-core/src/main/java/org/apache/activemq/security/JassAuthenticationPlugin.java @@ -0,0 +1,87 @@ +/** + * + * Copyright 2005-2006 The Apache Software Foundation + * + * Licensed 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.security; + +import org.apache.activemq.broker.Broker; +import org.apache.activemq.broker.BrokerPlugin; + +import java.net.URL; + +/** + * Adds a JAAS based authentication security plugin + * + * @org.apache.xbean.XBean description="Provides a JAAS based authentication plugin" + * + * @version $Revision$ + */ +public class JassAuthenticationPlugin implements BrokerPlugin { + + private String configuration = "activemq-domain"; + private boolean discoverLoginConfig = true; + + public Broker installPlugin(Broker broker) { + initialiseJaas(); + return new JaasAuthenticationBroker(broker, configuration); + } + + + // Properties + // ------------------------------------------------------------------------- + public String getConfiguration() { + return configuration; + } + + /** + * Sets the JAAS configuration domain name used + */ + public void setConfiguration(String jaasConfiguration) { + this.configuration = jaasConfiguration; + } + + + public boolean isDiscoverLoginConfig() { + return discoverLoginConfig; + } + + /** + * Enables or disables the auto-discovery of the login.config file for JAAS to initialize itself. + * This flag is enabled by default such that if the java.security.auth.login.config system property + * is not defined then it is set to the location of the login.config file on the classpath. + */ + public void setDiscoverLoginConfig(boolean discoverLoginConfig) { + this.discoverLoginConfig = discoverLoginConfig; + } + + // Implementation methods + // ------------------------------------------------------------------------- + protected void initialiseJaas() { + if (discoverLoginConfig) { + String path = System.getProperty("java.security.auth.login.config"); + if (path == null) { + //URL resource = Thread.currentThread().getContextClassLoader().getResource("login.config"); + URL resource = null; + if (resource == null) { + resource = getClass().getClassLoader().getResource("login.config"); + } + if (resource != null) { + path = resource.getFile(); + System.setProperty("java.security.auth.login.config", path); + } + } + } + } +} diff --git a/activemq-core/src/main/java/org/apache/activemq/security/SimpleAuthenticationPlugin.java b/activemq-core/src/main/java/org/apache/activemq/security/SimpleAuthenticationPlugin.java new file mode 100644 index 0000000000..7b08329229 --- /dev/null +++ b/activemq-core/src/main/java/org/apache/activemq/security/SimpleAuthenticationPlugin.java @@ -0,0 +1,62 @@ +/** + * + * Copyright 2005-2006 The Apache Software Foundation + * + * Licensed 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.security; + +import org.apache.activemq.broker.Broker; +import org.apache.activemq.broker.BrokerPlugin; + +import java.util.Map; + +/** + * A simple authentication plugin + * + * @org.apache.xbean.XBean element="simpleAuthenticationPlugin" description="Provides a simple authentication + * plugin configured with a map of user-passwords and a map of user-groups" + * + * @version $Revision$ + */ +public class SimpleAuthenticationPlugin implements BrokerPlugin { + private Map userPasswords; + private Map userGroups; + + public Broker installPlugin(Broker broker) { + return new SimpleAuthenticationBroker(broker, userPasswords, userGroups); + } + + public Map getUserGroups() { + return userGroups; + } + + /** + * Sets the groups a user is in. The key is the user name and the value is a Set of groups + */ + public void setUserGroups(Map userGroups) { + this.userGroups = userGroups; + } + + public Map getUserPasswords() { + return userPasswords; + } + + /** + * Sets the map indexed by user name with the value the password + */ + public void setUserPasswords(Map userPasswords) { + this.userPasswords = userPasswords; + } + +} diff --git a/activemq-core/src/main/java/org/apache/activemq/security/SimpleAuthorizationPlugin.java b/activemq-core/src/main/java/org/apache/activemq/security/SimpleAuthorizationPlugin.java new file mode 100644 index 0000000000..886c97baeb --- /dev/null +++ b/activemq-core/src/main/java/org/apache/activemq/security/SimpleAuthorizationPlugin.java @@ -0,0 +1,65 @@ +/** + * + * Copyright 2005-2006 The Apache Software Foundation + * + * Licensed 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.security; + +import org.apache.activemq.broker.Broker; +import org.apache.activemq.broker.BrokerPlugin; +import org.apache.activemq.filter.DestinationMap; + +/** + * A simple authorization plugin + * + * @org.apache.xbean.XBean element="simpleAuthorizationPlugin" description="Provides a simple authorization + * plugin where each ACL is a destination map of destinations to role names" + * + * @version $Revision$ + */ +public class SimpleAuthorizationPlugin implements BrokerPlugin { + + private DestinationMap writeACLs; + private DestinationMap readACLs; + private DestinationMap adminACLs; + + public Broker installPlugin(Broker broker) { + return new SimpleAuthorizationBroker(broker, writeACLs, readACLs, adminACLs); + } + + public DestinationMap getAdminACLs() { + return adminACLs; + } + + public void setAdminACLs(DestinationMap adminACLs) { + this.adminACLs = adminACLs; + } + + public DestinationMap getReadACLs() { + return readACLs; + } + + public void setReadACLs(DestinationMap readACLs) { + this.readACLs = readACLs; + } + + public DestinationMap getWriteACLs() { + return writeACLs; + } + + public void setWriteACLs(DestinationMap writeACLs) { + this.writeACLs = writeACLs; + } + +} diff --git a/activemq-core/src/test/java/org/apache/activemq/security/SecurityTestSupport.java b/activemq-core/src/test/java/org/apache/activemq/security/SecurityTestSupport.java new file mode 100644 index 0000000000..08702a3abc --- /dev/null +++ b/activemq-core/src/test/java/org/apache/activemq/security/SecurityTestSupport.java @@ -0,0 +1,168 @@ +/** + * + * Copyright 2005-2006 The Apache Software Foundation + * + * Licensed 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.security; + +import org.apache.activemq.JmsTestSupport; +import org.apache.activemq.command.ActiveMQDestination; + +import javax.jms.Connection; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.Session; +import javax.jms.TextMessage; + +/** + * + * @version $Revision$ + */ +public class SecurityTestSupport extends JmsTestSupport { + + public ActiveMQDestination destination; + + public void testUserReceiveFails() throws JMSException { + doReceive(true); + } + + public void testInvalidAuthentication() throws JMSException { + try { + // No user id + Connection c = factory.createConnection(); + connections.add(c); + c.start(); + fail("Expected exception."); + } + catch (JMSException e) { + } + + try { + // Bad password + Connection c = factory.createConnection("user", "krap"); + connections.add(c); + c.start(); + fail("Expected exception."); + } + catch (JMSException e) { + } + + try { + // Bad userid + Connection c = factory.createConnection("userkrap", null); + connections.add(c); + c.start(); + fail("Expected exception."); + } + catch (JMSException e) { + } + } + + public void testUserReceiveSucceeds() throws JMSException { + doReceive(false); + } + + public void testGuestReceiveSucceeds() throws JMSException { + doReceive(false); + } + + public void testGuestReceiveFails() throws JMSException { + doReceive(true); + } + + public void testUserSendSucceeds() throws JMSException { + doSend(false); + } + + public void testUserSendFails() throws JMSException { + doSend(true); + } + + public void testGuestSendFails() throws JMSException { + doSend(true); + } + + public void testGuestSendSucceeds() throws JMSException { + doSend(false); + } + + /** + * @throws JMSException + */ + public void doSend(boolean fail) throws JMSException { + + Connection adminConnection = factory.createConnection("system", "manager"); + connections.add(adminConnection); + + adminConnection.start(); + Session adminSession = adminConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageConsumer consumer = adminSession.createConsumer(destination); + + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + try { + sendMessages(session, destination, 1); + } + catch (JMSException e) { + // If test is expected to fail, the cause must only be a + // SecurityException + // otherwise rethrow the exception + if (!fail || !(e.getCause() instanceof SecurityException)) { + throw e; + } + } + + Message m = consumer.receive(1000); + if (fail) + assertNull(m); + else { + assertNotNull(m); + assertEquals("0", ((TextMessage) m).getText()); + assertNull(consumer.receiveNoWait()); + } + + } + + /** + * @throws JMSException + */ + public void doReceive(boolean fail) throws JMSException { + + connection.start(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageConsumer consumer = null; + try { + consumer = session.createConsumer(destination); + if (fail) + fail("Expected failure due to security constraint."); + } + catch (JMSException e) { + if (fail && e.getCause() instanceof SecurityException) + return; + throw e; + } + + Connection adminConnection = factory.createConnection("system", "manager"); + connections.add(adminConnection); + Session adminSession = adminConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + sendMessages(adminSession, destination, 1); + + Message m = consumer.receive(1000); + assertNotNull(m); + assertEquals("0", ((TextMessage) m).getText()); + assertNull(consumer.receiveNoWait()); + + } + +} diff --git a/activemq-core/src/test/java/org/apache/activemq/security/SimpleSecurityBrokerSystemTest.java b/activemq-core/src/test/java/org/apache/activemq/security/SimpleSecurityBrokerSystemTest.java index a85557ee57..255f3578bc 100644 --- a/activemq-core/src/test/java/org/apache/activemq/security/SimpleSecurityBrokerSystemTest.java +++ b/activemq-core/src/test/java/org/apache/activemq/security/SimpleSecurityBrokerSystemTest.java @@ -16,55 +16,39 @@ */ package org.apache.activemq.security; -import java.io.IOException; +import org.apache.activemq.broker.Broker; +import org.apache.activemq.broker.BrokerPlugin; +import org.apache.activemq.broker.BrokerService; +import org.apache.activemq.command.ActiveMQQueue; +import org.apache.activemq.command.ActiveMQTopic; +import org.apache.activemq.filter.DestinationMap; +import org.apache.activemq.jaas.GroupPrincipal; + import java.net.URL; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; -import javax.jms.Connection; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.Session; -import javax.jms.TextMessage; - import junit.framework.Test; -import org.apache.activemq.JmsTestSupport; -import org.apache.activemq.broker.Broker; -import org.apache.activemq.broker.BrokerService; -import org.apache.activemq.command.ActiveMQDestination; -import org.apache.activemq.command.ActiveMQQueue; -import org.apache.activemq.command.ActiveMQTopic; -import org.apache.activemq.filter.DestinationMap; -import org.apache.activemq.jaas.GroupPrincipal; -import org.apache.activemq.security.JaasAuthenticationBroker; -import org.apache.activemq.security.SimpleAuthenticationBroker; -import org.apache.activemq.security.SimpleAuthorizationBroker; - /** * Tests that the broker allows/fails access to destinations based on the * security policy installed on the broker. * * @version $Revision$ */ -public class SimpleSecurityBrokerSystemTest extends JmsTestSupport { +public class SimpleSecurityBrokerSystemTest extends SecurityTestSupport { static final GroupPrincipal guests = new GroupPrincipal("guests"); static final GroupPrincipal users = new GroupPrincipal("users"); static final GroupPrincipal admins = new GroupPrincipal("admins"); - public ActiveMQDestination destination; - public SecurityFactory authorizationFactory; - public SecurityFactory authenticationFactory; + public BrokerPlugin authorizationPlugin; + public BrokerPlugin authenticationPlugin; - interface SecurityFactory { - public Broker create(Broker broker); - } - class SimpleAuthorizationFactory implements SecurityFactory { - public Broker create(Broker broker) { + class SimpleAuthorizationFactory implements BrokerPlugin { + public Broker installPlugin(Broker broker) { DestinationMap readAccess = new DestinationMap(); readAccess.put(new ActiveMQQueue(">"), admins); @@ -104,8 +88,8 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport { } } - class SimpleAuthenticationFactory implements SecurityFactory { - public Broker create(Broker broker) { + class SimpleAuthenticationFactory implements BrokerPlugin { + public Broker installPlugin(Broker broker) { HashMap u = new HashMap(); u.put("system", "manager"); @@ -136,15 +120,6 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport { System.out.println("Path to login config: "+path); } - class JaasAuthenticationFactory implements SecurityFactory { - public Broker create(Broker broker) { - return new JaasAuthenticationBroker(broker, "activemq-test-domain"); - } - public String toString() { - return "JassAuthenticationBroker"; - } - } - public static Test suite() { return suite(SimpleSecurityBrokerSystemTest.class); } @@ -154,24 +129,18 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport { } public void initCombos() { - addCombinationValues("authorizationFactory", new Object[] { + addCombinationValues("authorizationPlugin", new Object[] { new SimpleAuthorizationFactory(), }); - addCombinationValues("authenticationFactory", new Object[] { + addCombinationValues("authenticationPlugin", new Object[] { new SimpleAuthenticationFactory(), - new JaasAuthenticationFactory(), + new JassAuthenticationPlugin(), }); } protected BrokerService createBroker() throws Exception { - BrokerService broker = new BrokerService() { - protected Broker addInterceptors(Broker broker) throws IOException { - broker = super.addInterceptors(broker); - broker = authorizationFactory.create(broker); - broker = authenticationFactory.create(broker); - return broker; - } - }; + BrokerService broker = new BrokerService(); + broker.setPlugins(new BrokerPlugin[] {authorizationPlugin, authenticationPlugin}); broker.setPersistent(false); return broker; } @@ -186,44 +155,10 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport { new ActiveMQTopic("GUEST.BAR"), }); } - public void testUserReceiveFails() throws JMSException { - doReceive(true); - } - - public void initCombosForTestInvalidAuthentication() { addCombinationValues("userName", new Object[] {"user"}); addCombinationValues("password", new Object[] {"password"}); } - public void testInvalidAuthentication() throws JMSException { - try { - // No user id - Connection c= factory.createConnection(); - connections.add(c); - c.start(); - fail("Expected exception."); - } catch (JMSException e) { - } - - try { - // Bad password - Connection c = factory.createConnection("user", "krap"); - connections.add(c); - c.start(); - fail("Expected exception."); - } catch (JMSException e) { - } - - try { - // Bad userid - Connection c = factory.createConnection("userkrap", null); - connections.add(c); - c.start(); - fail("Expected exception."); - } catch (JMSException e) { - } - } - public void initCombosForTestUserReceiveSucceeds() { addCombinationValues("userName", new Object[] {"user"}); addCombinationValues("password", new Object[] {"password"}); @@ -232,11 +167,6 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport { new ActiveMQTopic("USERS.FOO"), }); } - public void testUserReceiveSucceeds() throws JMSException { - doReceive(false); - } - - public void initCombosForTestGuestReceiveSucceeds() { addCombinationValues("userName", new Object[] {"guest"}); addCombinationValues("password", new Object[] {"password"}); @@ -245,10 +175,6 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport { new ActiveMQTopic("GUEST.BAR"), }); } - public void testGuestReceiveSucceeds() throws JMSException { - doReceive(false); - } - public void initCombosForTestGuestReceiveFails() { addCombinationValues("userName", new Object[] {"guest"}); addCombinationValues("password", new Object[] {"password"}); @@ -259,11 +185,6 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport { new ActiveMQTopic("USERS.FOO"), }); } - public void testGuestReceiveFails() throws JMSException { - doReceive(true); - } - - public void initCombosForTestUserSendSucceeds() { addCombinationValues("userName", new Object[] {"user"}); addCombinationValues("password", new Object[] {"password"}); @@ -274,10 +195,6 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport { new ActiveMQTopic("GUEST.BAR"), }); } - public void testUserSendSucceeds() throws JMSException { - doSend(false); - } - public void initCombosForTestUserSendFails() { addCombinationValues("userName", new Object[] {"user"}); addCombinationValues("password", new Object[] {"password"}); @@ -286,11 +203,6 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport { new ActiveMQTopic("TEST"), }); } - public void testUserSendFails() throws JMSException { - doSend(true); - } - - public void initCombosForTestGuestSendFails() { addCombinationValues("userName", new Object[] {"guest"}); addCombinationValues("password", new Object[] {"password"}); @@ -301,10 +213,6 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport { new ActiveMQTopic("USERS.FOO"), }); } - public void testGuestSendFails() throws JMSException { - doSend(true); - } - public void initCombosForTestGuestSendSucceeds() { addCombinationValues("userName", new Object[] {"guest"}); addCombinationValues("password", new Object[] {"password"}); @@ -313,71 +221,4 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport { new ActiveMQTopic("GUEST.BAR"), }); } - public void testGuestSendSucceeds() throws JMSException { - doSend(false); - } - - /** - * @throws JMSException - */ - public void doSend(boolean fail) throws JMSException { - - Connection adminConnection = factory.createConnection("system", "manager"); - connections.add(adminConnection); - - adminConnection.start(); - Session adminSession = adminConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageConsumer consumer = adminSession.createConsumer(destination); - - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - try { - sendMessages(session, destination, 1); - } catch (JMSException e) { - // If test is expected to fail, the cause must only be a SecurityException - // otherwise rethrow the exception - if (!fail || !(e.getCause() instanceof SecurityException)) { - throw e; - } - } - - Message m = consumer.receive(1000); - if(fail) - assertNull(m); - else { - assertNotNull(m); - assertEquals("0", ((TextMessage)m).getText()); - assertNull(consumer.receiveNoWait()); - } - - } - - /** - * @throws JMSException - */ - public void doReceive(boolean fail) throws JMSException { - - connection.start(); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageConsumer consumer=null; - try { - consumer = session.createConsumer(destination); - if( fail ) - fail("Expected failure due to security constraint."); - } catch (JMSException e) { - if (fail && e.getCause() instanceof SecurityException) - return; - throw e; - } - - Connection adminConnection = factory.createConnection("system", "manager"); - connections.add(adminConnection); - Session adminSession = adminConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); - sendMessages(adminSession, destination, 1); - - Message m = consumer.receive(1000); - assertNotNull(m); - assertEquals("0", ((TextMessage)m).getText()); - assertNull(consumer.receiveNoWait()); - - } } diff --git a/activemq-core/src/test/resources/login.config b/activemq-core/src/test/resources/login.config index 35f428ac50..e0a762f7ff 100644 --- a/activemq-core/src/test/resources/login.config +++ b/activemq-core/src/test/resources/login.config @@ -1,4 +1,4 @@ -activemq-test-domain { +activemq-domain { org.apache.activemq.jaas.PropertiesLoginModule required debug=true org.apache.activemq.jaas.properties.user="org/apache/activemq/security/users.properties" diff --git a/activemq-core/src/test/resources/org/apache/activemq/security/jaas-broker.xml b/activemq-core/src/test/resources/org/apache/activemq/security/jaas-broker.xml new file mode 100644 index 0000000000..770485b86d --- /dev/null +++ b/activemq-core/src/test/resources/org/apache/activemq/security/jaas-broker.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + +