mirror of https://github.com/apache/activemq.git
added a BrokerPlugin mechanism to allow users to customize the Broker interceptor stack
git-svn-id: https://svn.apache.org/repos/asf/incubator/activemq/trunk@377991 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7b945f9d92
commit
4686ec5f0b
|
@ -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);
|
||||||
|
|
||||||
|
}
|
|
@ -112,6 +112,7 @@ public class BrokerService implements Service {
|
||||||
private URI vmConnectorURI;
|
private URI vmConnectorURI;
|
||||||
private PolicyMap destinationPolicy;
|
private PolicyMap destinationPolicy;
|
||||||
private AtomicBoolean started = new AtomicBoolean(false);
|
private AtomicBoolean started = new AtomicBoolean(false);
|
||||||
|
private BrokerPlugin[] plugins;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new transport connector for the given bind address
|
* Adds a new transport connector for the given bind address
|
||||||
|
@ -677,6 +678,17 @@ public class BrokerService implements Service {
|
||||||
this.destinationPolicy = policyMap;
|
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
|
// Implementation methods
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
|
@ -876,6 +888,12 @@ public class BrokerService implements Service {
|
||||||
if (isPopulateJMSXUserID()) {
|
if (isPopulateJMSXUserID()) {
|
||||||
broker = new UserIDBroker(broker);
|
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;
|
return broker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 <b>java.security.auth.login.config</b> system property
|
||||||
|
* is not defined then it is set to the location of the <b>login.config</b> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,55 +16,39 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.activemq.security;
|
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.net.URL;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
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 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
|
* Tests that the broker allows/fails access to destinations based on the
|
||||||
* security policy installed on the broker.
|
* security policy installed on the broker.
|
||||||
*
|
*
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
public class SimpleSecurityBrokerSystemTest extends JmsTestSupport {
|
public class SimpleSecurityBrokerSystemTest extends SecurityTestSupport {
|
||||||
|
|
||||||
static final GroupPrincipal guests = new GroupPrincipal("guests");
|
static final GroupPrincipal guests = new GroupPrincipal("guests");
|
||||||
static final GroupPrincipal users = new GroupPrincipal("users");
|
static final GroupPrincipal users = new GroupPrincipal("users");
|
||||||
static final GroupPrincipal admins = new GroupPrincipal("admins");
|
static final GroupPrincipal admins = new GroupPrincipal("admins");
|
||||||
|
|
||||||
public ActiveMQDestination destination;
|
public BrokerPlugin authorizationPlugin;
|
||||||
public SecurityFactory authorizationFactory;
|
public BrokerPlugin authenticationPlugin;
|
||||||
public SecurityFactory authenticationFactory;
|
|
||||||
|
|
||||||
interface SecurityFactory {
|
|
||||||
public Broker create(Broker broker);
|
|
||||||
}
|
|
||||||
|
|
||||||
class SimpleAuthorizationFactory implements SecurityFactory {
|
class SimpleAuthorizationFactory implements BrokerPlugin {
|
||||||
public Broker create(Broker broker) {
|
public Broker installPlugin(Broker broker) {
|
||||||
|
|
||||||
DestinationMap readAccess = new DestinationMap();
|
DestinationMap readAccess = new DestinationMap();
|
||||||
readAccess.put(new ActiveMQQueue(">"), admins);
|
readAccess.put(new ActiveMQQueue(">"), admins);
|
||||||
|
@ -104,8 +88,8 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SimpleAuthenticationFactory implements SecurityFactory {
|
class SimpleAuthenticationFactory implements BrokerPlugin {
|
||||||
public Broker create(Broker broker) {
|
public Broker installPlugin(Broker broker) {
|
||||||
|
|
||||||
HashMap u = new HashMap();
|
HashMap u = new HashMap();
|
||||||
u.put("system", "manager");
|
u.put("system", "manager");
|
||||||
|
@ -136,15 +120,6 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport {
|
||||||
System.out.println("Path to login config: "+path);
|
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() {
|
public static Test suite() {
|
||||||
return suite(SimpleSecurityBrokerSystemTest.class);
|
return suite(SimpleSecurityBrokerSystemTest.class);
|
||||||
}
|
}
|
||||||
|
@ -154,24 +129,18 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initCombos() {
|
public void initCombos() {
|
||||||
addCombinationValues("authorizationFactory", new Object[] {
|
addCombinationValues("authorizationPlugin", new Object[] {
|
||||||
new SimpleAuthorizationFactory(),
|
new SimpleAuthorizationFactory(),
|
||||||
});
|
});
|
||||||
addCombinationValues("authenticationFactory", new Object[] {
|
addCombinationValues("authenticationPlugin", new Object[] {
|
||||||
new SimpleAuthenticationFactory(),
|
new SimpleAuthenticationFactory(),
|
||||||
new JaasAuthenticationFactory(),
|
new JassAuthenticationPlugin(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BrokerService createBroker() throws Exception {
|
protected BrokerService createBroker() throws Exception {
|
||||||
BrokerService broker = new BrokerService() {
|
BrokerService broker = new BrokerService();
|
||||||
protected Broker addInterceptors(Broker broker) throws IOException {
|
broker.setPlugins(new BrokerPlugin[] {authorizationPlugin, authenticationPlugin});
|
||||||
broker = super.addInterceptors(broker);
|
|
||||||
broker = authorizationFactory.create(broker);
|
|
||||||
broker = authenticationFactory.create(broker);
|
|
||||||
return broker;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
broker.setPersistent(false);
|
broker.setPersistent(false);
|
||||||
return broker;
|
return broker;
|
||||||
}
|
}
|
||||||
|
@ -186,44 +155,10 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport {
|
||||||
new ActiveMQTopic("GUEST.BAR"),
|
new ActiveMQTopic("GUEST.BAR"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public void testUserReceiveFails() throws JMSException {
|
|
||||||
doReceive(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void initCombosForTestInvalidAuthentication() {
|
public void initCombosForTestInvalidAuthentication() {
|
||||||
addCombinationValues("userName", new Object[] {"user"});
|
addCombinationValues("userName", new Object[] {"user"});
|
||||||
addCombinationValues("password", new Object[] {"password"});
|
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() {
|
public void initCombosForTestUserReceiveSucceeds() {
|
||||||
addCombinationValues("userName", new Object[] {"user"});
|
addCombinationValues("userName", new Object[] {"user"});
|
||||||
addCombinationValues("password", new Object[] {"password"});
|
addCombinationValues("password", new Object[] {"password"});
|
||||||
|
@ -232,11 +167,6 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport {
|
||||||
new ActiveMQTopic("USERS.FOO"),
|
new ActiveMQTopic("USERS.FOO"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public void testUserReceiveSucceeds() throws JMSException {
|
|
||||||
doReceive(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void initCombosForTestGuestReceiveSucceeds() {
|
public void initCombosForTestGuestReceiveSucceeds() {
|
||||||
addCombinationValues("userName", new Object[] {"guest"});
|
addCombinationValues("userName", new Object[] {"guest"});
|
||||||
addCombinationValues("password", new Object[] {"password"});
|
addCombinationValues("password", new Object[] {"password"});
|
||||||
|
@ -245,10 +175,6 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport {
|
||||||
new ActiveMQTopic("GUEST.BAR"),
|
new ActiveMQTopic("GUEST.BAR"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public void testGuestReceiveSucceeds() throws JMSException {
|
|
||||||
doReceive(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initCombosForTestGuestReceiveFails() {
|
public void initCombosForTestGuestReceiveFails() {
|
||||||
addCombinationValues("userName", new Object[] {"guest"});
|
addCombinationValues("userName", new Object[] {"guest"});
|
||||||
addCombinationValues("password", new Object[] {"password"});
|
addCombinationValues("password", new Object[] {"password"});
|
||||||
|
@ -259,11 +185,6 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport {
|
||||||
new ActiveMQTopic("USERS.FOO"),
|
new ActiveMQTopic("USERS.FOO"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public void testGuestReceiveFails() throws JMSException {
|
|
||||||
doReceive(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void initCombosForTestUserSendSucceeds() {
|
public void initCombosForTestUserSendSucceeds() {
|
||||||
addCombinationValues("userName", new Object[] {"user"});
|
addCombinationValues("userName", new Object[] {"user"});
|
||||||
addCombinationValues("password", new Object[] {"password"});
|
addCombinationValues("password", new Object[] {"password"});
|
||||||
|
@ -274,10 +195,6 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport {
|
||||||
new ActiveMQTopic("GUEST.BAR"),
|
new ActiveMQTopic("GUEST.BAR"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public void testUserSendSucceeds() throws JMSException {
|
|
||||||
doSend(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initCombosForTestUserSendFails() {
|
public void initCombosForTestUserSendFails() {
|
||||||
addCombinationValues("userName", new Object[] {"user"});
|
addCombinationValues("userName", new Object[] {"user"});
|
||||||
addCombinationValues("password", new Object[] {"password"});
|
addCombinationValues("password", new Object[] {"password"});
|
||||||
|
@ -286,11 +203,6 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport {
|
||||||
new ActiveMQTopic("TEST"),
|
new ActiveMQTopic("TEST"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public void testUserSendFails() throws JMSException {
|
|
||||||
doSend(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void initCombosForTestGuestSendFails() {
|
public void initCombosForTestGuestSendFails() {
|
||||||
addCombinationValues("userName", new Object[] {"guest"});
|
addCombinationValues("userName", new Object[] {"guest"});
|
||||||
addCombinationValues("password", new Object[] {"password"});
|
addCombinationValues("password", new Object[] {"password"});
|
||||||
|
@ -301,10 +213,6 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport {
|
||||||
new ActiveMQTopic("USERS.FOO"),
|
new ActiveMQTopic("USERS.FOO"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public void testGuestSendFails() throws JMSException {
|
|
||||||
doSend(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initCombosForTestGuestSendSucceeds() {
|
public void initCombosForTestGuestSendSucceeds() {
|
||||||
addCombinationValues("userName", new Object[] {"guest"});
|
addCombinationValues("userName", new Object[] {"guest"});
|
||||||
addCombinationValues("password", new Object[] {"password"});
|
addCombinationValues("password", new Object[] {"password"});
|
||||||
|
@ -313,71 +221,4 @@ public class SimpleSecurityBrokerSystemTest extends JmsTestSupport {
|
||||||
new ActiveMQTopic("GUEST.BAR"),
|
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());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
activemq-test-domain {
|
activemq-domain {
|
||||||
org.apache.activemq.jaas.PropertiesLoginModule required
|
org.apache.activemq.jaas.PropertiesLoginModule required
|
||||||
debug=true
|
debug=true
|
||||||
org.apache.activemq.jaas.properties.user="org/apache/activemq/security/users.properties"
|
org.apache.activemq.jaas.properties.user="org/apache/activemq/security/users.properties"
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- this file can only be parsed using the xbean-spring library -->
|
||||||
|
<!-- START SNIPPET: xbean -->
|
||||||
|
<beans xmlns="http://activemq.org/config/1.0">
|
||||||
|
|
||||||
|
<broker useJmx="false" persistent="false">
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<!-- use JAAS to authenticate using the login.config file on the classpath to configure JAAS -->
|
||||||
|
<jassAuthenticationPlugin configuration="activemq-domain"/>
|
||||||
|
</plugins>
|
||||||
|
</broker>
|
||||||
|
|
||||||
|
</beans>
|
||||||
|
<!-- END SNIPPET: xbean -->
|
Loading…
Reference in New Issue