mirror of https://github.com/apache/activemq.git
Applied patch for AMQ-826 with thanks. This patch adds an LDAP based authorization map. I"ve added the test case but disabled it so far - I've not figured out the magic combination of jars and versions and spring.xml configuration files to boot up ApacheDS in Spring for the test case - it seems the online documentation nor the spring.xml that comes with the 1.0-RC3 download actually work
git-svn-id: https://svn.apache.org/repos/asf/incubator/activemq/trunk@430034 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
171e3223c1
commit
3e945b5a91
|
@ -195,6 +195,19 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- LDAP tests -->
|
||||
<dependency>
|
||||
<groupId>org.apache.directory.server</groupId>
|
||||
<artifactId>apacheds-core</artifactId>
|
||||
<version>1.0-RC3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>nlog4j</artifactId>
|
||||
<version>1.2.24</version>
|
||||
<scope>est</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -279,6 +292,10 @@
|
|||
|
||||
<!-- This test only works on machines which have ssh propertly configured -->
|
||||
<exclude>**/SSHTunnelNetworkReconnectTest.*</exclude>
|
||||
|
||||
<!-- see http://issues.apache.org/activemq/browse/AMQ-826 -->
|
||||
<!-- have not yet figured out the way to configure ApacheDS via Spring -->
|
||||
<exclude>**/LDAPAuthorizationMapTest.*</exclude>
|
||||
|
||||
</excludes>
|
||||
</configuration>
|
||||
|
|
|
@ -0,0 +1,401 @@
|
|||
/**
|
||||
*
|
||||
* 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.security;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.jaas.GroupPrincipal;
|
||||
import org.apache.activemq.jaas.LDAPLoginModule;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* An {@link AuthorizationMap} which uses LDAP
|
||||
*
|
||||
* @org.apache.xbean.XBean
|
||||
*
|
||||
* @author ngcutura
|
||||
*/
|
||||
public class LDAPAuthorizationMap implements AuthorizationMap {
|
||||
|
||||
private static Log log = LogFactory.getLog(LDAPLoginModule.class);
|
||||
|
||||
public static final String INITIAL_CONTEXT_FACTORY = "initialContextFactory";
|
||||
public static final String CONNECTION_URL = "connectionURL";
|
||||
public static final String CONNECTION_USERNAME = "connectionUsername";
|
||||
public static final String CONNECTION_PASSWORD = "connectionPassword";
|
||||
public static final String CONNECTION_PROTOCOL = "connectionProtocol";
|
||||
public static final String AUTHENTICATION = "authentication";
|
||||
|
||||
public static final String TOPIC_SEARCH_MATCHING = "topicSearchMatching";
|
||||
public static final String TOPIC_SEARCH_SUBTREE = "topicSearchSubtree";
|
||||
public static final String QUEUE_SEARCH_MATCHING = "queueSearchMatching";
|
||||
public static final String QUEUE_SEARCH_SUBTREE = "queueSearchSubtree";
|
||||
|
||||
public static final String ADMIN_BASE = "adminBase";
|
||||
public static final String ADMIN_ATTRIBUTE = "adminAttribute";
|
||||
public static final String READ_BASE = "readBase";
|
||||
public static final String READ_ATTRIBUTE = "readAttribute";
|
||||
public static final String WRITE_BASE = "writeBAse";
|
||||
public static final String WRITE_ATTRIBUTE = "writeAttribute";
|
||||
|
||||
private String initialContextFactory;
|
||||
private String connectionURL;
|
||||
private String connectionUsername;
|
||||
private String connectionPassword;
|
||||
private String connectionProtocol;
|
||||
private String authentication;
|
||||
|
||||
private DirContext context;
|
||||
|
||||
private MessageFormat topicSearchMatchingFormat;
|
||||
private MessageFormat queueSearchMatchingFormat;
|
||||
|
||||
private boolean topicSearchSubtreeBool = true;
|
||||
private boolean queueSearchSubtreeBool = true;
|
||||
|
||||
private String adminBase;
|
||||
private String adminAttribute;
|
||||
private String readBase;
|
||||
private String readAttribute;
|
||||
private String writeBase;
|
||||
private String writeAttribute;
|
||||
|
||||
public LDAPAuthorizationMap() {
|
||||
// lets setup some sensible defaults
|
||||
initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
|
||||
connectionURL = "ldap://localhost:10389";
|
||||
connectionUsername = "uid=admin,ou=system";
|
||||
connectionPassword = "secret";
|
||||
connectionProtocol = "s";
|
||||
authentication = "simple";
|
||||
|
||||
topicSearchMatchingFormat = new MessageFormat("uid={0},ou=topics,ou=destinations,o=ActiveMQ,dc=example,dc=com");
|
||||
queueSearchMatchingFormat = new MessageFormat("uid={0},ou=queues,ou=destinations,o=ActiveMQ,dc=example,dc=com");
|
||||
|
||||
adminBase = "(cn=admin)";
|
||||
adminAttribute = "uniqueMember";
|
||||
readBase = "(cn=read)";
|
||||
readAttribute = "uniqueMember";
|
||||
writeBase = "(cn=write)";
|
||||
writeAttribute = "uniqueMember";
|
||||
}
|
||||
|
||||
public LDAPAuthorizationMap(Map options) {
|
||||
initialContextFactory = (String) options.get(INITIAL_CONTEXT_FACTORY);
|
||||
connectionURL = (String) options.get(CONNECTION_URL);
|
||||
connectionUsername = (String) options.get(CONNECTION_USERNAME);
|
||||
connectionPassword = (String) options.get(CONNECTION_PASSWORD);
|
||||
connectionProtocol = (String) options.get(CONNECTION_PROTOCOL);
|
||||
authentication = (String) options.get(AUTHENTICATION);
|
||||
|
||||
adminBase = (String) options.get(ADMIN_BASE);
|
||||
adminAttribute = (String) options.get(ADMIN_ATTRIBUTE);
|
||||
readBase = (String) options.get(READ_BASE);
|
||||
readAttribute = (String) options.get(READ_ATTRIBUTE);
|
||||
writeBase = (String) options.get(WRITE_BASE);
|
||||
writeAttribute = (String) options.get(WRITE_ATTRIBUTE);
|
||||
|
||||
String topicSearchMatching = (String) options.get(TOPIC_SEARCH_MATCHING);
|
||||
String topicSearchSubtree = (String) options.get(TOPIC_SEARCH_SUBTREE);
|
||||
String queueSearchMatching = (String) options.get(QUEUE_SEARCH_MATCHING);
|
||||
String queueSearchSubtree = (String) options.get(QUEUE_SEARCH_SUBTREE);
|
||||
topicSearchMatchingFormat = new MessageFormat(topicSearchMatching);
|
||||
queueSearchMatchingFormat = new MessageFormat(queueSearchMatching);
|
||||
topicSearchSubtreeBool = new Boolean(topicSearchSubtree).booleanValue();
|
||||
queueSearchSubtreeBool = new Boolean(queueSearchSubtree).booleanValue();
|
||||
}
|
||||
|
||||
public Set getAdminACLs(ActiveMQDestination destination) {
|
||||
return getACLs(destination, adminBase, adminAttribute);
|
||||
}
|
||||
|
||||
public Set getReadACLs(ActiveMQDestination destination) {
|
||||
return getACLs(destination, readBase, readAttribute);
|
||||
}
|
||||
|
||||
public Set getWriteACLs(ActiveMQDestination destination) {
|
||||
return getACLs(destination, writeBase, writeAttribute);
|
||||
}
|
||||
|
||||
// Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public String getAdminAttribute() {
|
||||
return adminAttribute;
|
||||
}
|
||||
|
||||
public void setAdminAttribute(String adminAttribute) {
|
||||
this.adminAttribute = adminAttribute;
|
||||
}
|
||||
|
||||
public String getAdminBase() {
|
||||
return adminBase;
|
||||
}
|
||||
|
||||
public void setAdminBase(String adminBase) {
|
||||
this.adminBase = adminBase;
|
||||
}
|
||||
|
||||
public String getAuthentication() {
|
||||
return authentication;
|
||||
}
|
||||
|
||||
public void setAuthentication(String authentication) {
|
||||
this.authentication = authentication;
|
||||
}
|
||||
|
||||
public String getConnectionPassword() {
|
||||
return connectionPassword;
|
||||
}
|
||||
|
||||
public void setConnectionPassword(String connectionPassword) {
|
||||
this.connectionPassword = connectionPassword;
|
||||
}
|
||||
|
||||
public String getConnectionProtocol() {
|
||||
return connectionProtocol;
|
||||
}
|
||||
|
||||
public void setConnectionProtocol(String connectionProtocol) {
|
||||
this.connectionProtocol = connectionProtocol;
|
||||
}
|
||||
|
||||
public String getConnectionURL() {
|
||||
return connectionURL;
|
||||
}
|
||||
|
||||
public void setConnectionURL(String connectionURL) {
|
||||
this.connectionURL = connectionURL;
|
||||
}
|
||||
|
||||
public String getConnectionUsername() {
|
||||
return connectionUsername;
|
||||
}
|
||||
|
||||
public void setConnectionUsername(String connectionUsername) {
|
||||
this.connectionUsername = connectionUsername;
|
||||
}
|
||||
|
||||
public DirContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public void setContext(DirContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public String getInitialContextFactory() {
|
||||
return initialContextFactory;
|
||||
}
|
||||
|
||||
public void setInitialContextFactory(String initialContextFactory) {
|
||||
this.initialContextFactory = initialContextFactory;
|
||||
}
|
||||
|
||||
public MessageFormat getQueueSearchMatchingFormat() {
|
||||
return queueSearchMatchingFormat;
|
||||
}
|
||||
|
||||
public void setQueueSearchMatchingFormat(MessageFormat queueSearchMatchingFormat) {
|
||||
this.queueSearchMatchingFormat = queueSearchMatchingFormat;
|
||||
}
|
||||
|
||||
public boolean isQueueSearchSubtreeBool() {
|
||||
return queueSearchSubtreeBool;
|
||||
}
|
||||
|
||||
public void setQueueSearchSubtreeBool(boolean queueSearchSubtreeBool) {
|
||||
this.queueSearchSubtreeBool = queueSearchSubtreeBool;
|
||||
}
|
||||
|
||||
public String getReadAttribute() {
|
||||
return readAttribute;
|
||||
}
|
||||
|
||||
public void setReadAttribute(String readAttribute) {
|
||||
this.readAttribute = readAttribute;
|
||||
}
|
||||
|
||||
public String getReadBase() {
|
||||
return readBase;
|
||||
}
|
||||
|
||||
public void setReadBase(String readBase) {
|
||||
this.readBase = readBase;
|
||||
}
|
||||
|
||||
public MessageFormat getTopicSearchMatchingFormat() {
|
||||
return topicSearchMatchingFormat;
|
||||
}
|
||||
|
||||
public void setTopicSearchMatchingFormat(MessageFormat topicSearchMatchingFormat) {
|
||||
this.topicSearchMatchingFormat = topicSearchMatchingFormat;
|
||||
}
|
||||
|
||||
public boolean isTopicSearchSubtreeBool() {
|
||||
return topicSearchSubtreeBool;
|
||||
}
|
||||
|
||||
public void setTopicSearchSubtreeBool(boolean topicSearchSubtreeBool) {
|
||||
this.topicSearchSubtreeBool = topicSearchSubtreeBool;
|
||||
}
|
||||
|
||||
public String getWriteAttribute() {
|
||||
return writeAttribute;
|
||||
}
|
||||
|
||||
public void setWriteAttribute(String writeAttribute) {
|
||||
this.writeAttribute = writeAttribute;
|
||||
}
|
||||
|
||||
public String getWriteBase() {
|
||||
return writeBase;
|
||||
}
|
||||
|
||||
public void setWriteBase(String writeBase) {
|
||||
this.writeBase = writeBase;
|
||||
}
|
||||
|
||||
// Implementation methods
|
||||
// -------------------------------------------------------------------------
|
||||
protected Set getACLs(ActiveMQDestination destination, String roleBase, String roleAttribute) {
|
||||
try {
|
||||
context = open();
|
||||
}
|
||||
catch (NamingException e) {
|
||||
log.error(e);
|
||||
return new HashSet();
|
||||
}
|
||||
|
||||
// if ((destination.getDestinationType() &
|
||||
// (ActiveMQDestination.QUEUE_TYPE | ActiveMQDestination.TOPIC_TYPE)) !=
|
||||
// 0)
|
||||
// return new HashSet();
|
||||
|
||||
String destinationBase = "";
|
||||
SearchControls constraints = new SearchControls();
|
||||
|
||||
if ((destination.getDestinationType() & ActiveMQDestination.QUEUE_TYPE) == ActiveMQDestination.QUEUE_TYPE) {
|
||||
destinationBase = queueSearchMatchingFormat.format(new String[] { destination.getPhysicalName() });
|
||||
if (queueSearchSubtreeBool) {
|
||||
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
}
|
||||
else {
|
||||
constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE);
|
||||
}
|
||||
}
|
||||
if ((destination.getDestinationType() & ActiveMQDestination.TOPIC_TYPE) == ActiveMQDestination.TOPIC_TYPE) {
|
||||
destinationBase = topicSearchMatchingFormat.format(new String[] { destination.getPhysicalName() });
|
||||
if (topicSearchSubtreeBool) {
|
||||
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
}
|
||||
else {
|
||||
constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE);
|
||||
}
|
||||
}
|
||||
|
||||
constraints.setReturningAttributes(new String[] { roleAttribute });
|
||||
|
||||
try {
|
||||
Set roles = new HashSet();
|
||||
Set acls = new HashSet();
|
||||
NamingEnumeration results = context.search(destinationBase, roleBase, constraints);
|
||||
while (results.hasMore()) {
|
||||
SearchResult result = (SearchResult) results.next();
|
||||
Attributes attrs = result.getAttributes();
|
||||
if (attrs == null) {
|
||||
continue;
|
||||
}
|
||||
acls = addAttributeValues(roleAttribute, attrs, acls);
|
||||
}
|
||||
for (Iterator iter = acls.iterator(); iter.hasNext();) {
|
||||
String roleName = (String) iter.next();
|
||||
roles.add(new GroupPrincipal(roleName));
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
catch (NamingException e) {
|
||||
log.error(e);
|
||||
return new HashSet();
|
||||
}
|
||||
}
|
||||
|
||||
protected Set addAttributeValues(String attrId, Attributes attrs, Set values) throws NamingException {
|
||||
if (attrId == null || attrs == null) {
|
||||
return values;
|
||||
}
|
||||
if (values == null) {
|
||||
values = new HashSet();
|
||||
}
|
||||
Attribute attr = attrs.get(attrId);
|
||||
if (attr == null) {
|
||||
return (values);
|
||||
}
|
||||
NamingEnumeration e = attr.getAll();
|
||||
while (e.hasMore()) {
|
||||
String value = (String) e.next();
|
||||
values.add(value);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
protected DirContext open() throws NamingException {
|
||||
if (context != null) {
|
||||
return context;
|
||||
}
|
||||
|
||||
try {
|
||||
Hashtable env = new Hashtable();
|
||||
env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
|
||||
if (connectionUsername != null || !"".equals(connectionUsername)) {
|
||||
env.put(Context.SECURITY_PRINCIPAL, connectionUsername);
|
||||
}
|
||||
if (connectionPassword != null || !"".equals(connectionPassword)) {
|
||||
env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
|
||||
}
|
||||
env.put(Context.SECURITY_PROTOCOL, connectionProtocol);
|
||||
env.put(Context.PROVIDER_URL, connectionURL);
|
||||
env.put(Context.SECURITY_AUTHENTICATION, authentication);
|
||||
context = new InitialDirContext(env);
|
||||
|
||||
}
|
||||
catch (NamingException e) {
|
||||
log.error(e);
|
||||
throw e;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
*
|
||||
* 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.security;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NameClassPair;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.ActiveMQTopic;
|
||||
import org.apache.activemq.jaas.GroupPrincipal;
|
||||
import org.apache.directory.server.core.configuration.StartupConfiguration;
|
||||
import org.apache.directory.server.core.jndi.CoreContextFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* This test assumes setup like in file 'AMQauth.ldif'. Contents of this file is
|
||||
* attached below in comments.
|
||||
*
|
||||
* @author ngcutura
|
||||
*
|
||||
*/
|
||||
public class LDAPAuthorizationMapTest extends TestCase {
|
||||
private HashMap options;
|
||||
private LDAPAuthorizationMap authMap;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
startLdapServer();
|
||||
|
||||
authMap = new LDAPAuthorizationMap();
|
||||
}
|
||||
|
||||
protected void startLdapServer() throws Exception {
|
||||
ApplicationContext factory = new ClassPathXmlApplicationContext("org/apache/activemq/security/ldap-spring.xml");
|
||||
StartupConfiguration cfg = (StartupConfiguration) factory.getBean("configuration");
|
||||
Properties env = (Properties) factory.getBean("environment");
|
||||
|
||||
env.setProperty(Context.PROVIDER_URL, "");
|
||||
env.setProperty(Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName());
|
||||
env.putAll(cfg.toJndiEnvironment());
|
||||
|
||||
new InitialDirContext(env);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testOpen() throws Exception {
|
||||
DirContext ctx = authMap.open();
|
||||
HashSet set = new HashSet();
|
||||
NamingEnumeration list = ctx.list("ou=destinations,o=ActiveMQ,dc=example,dc=com");
|
||||
while (list.hasMore()) {
|
||||
NameClassPair ncp = (NameClassPair) list.next();
|
||||
set.add(ncp.getName());
|
||||
}
|
||||
assertTrue(set.contains("ou=topics"));
|
||||
assertTrue(set.contains("ou=queues"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.activemq.security.LDAPAuthorizationMap.getAdminACLs(ActiveMQDestination)'
|
||||
*/
|
||||
public void testGetAdminACLs() {
|
||||
ActiveMQDestination q1 = new ActiveMQQueue("queue1");
|
||||
Set aclsq1 = authMap.getAdminACLs(q1);
|
||||
assertEquals(1, aclsq1.size());
|
||||
assertTrue(aclsq1.contains(new GroupPrincipal("role1")));
|
||||
|
||||
ActiveMQDestination t1 = new ActiveMQTopic("topic1");
|
||||
Set aclst1 = authMap.getAdminACLs(t1);
|
||||
assertEquals(1, aclst1.size());
|
||||
assertTrue(aclst1.contains(new GroupPrincipal("role1")));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.activemq.security.LDAPAuthorizationMap.getReadACLs(ActiveMQDestination)'
|
||||
*/
|
||||
public void testGetReadACLs() {
|
||||
ActiveMQDestination q1 = new ActiveMQQueue("queue1");
|
||||
Set aclsq1 = authMap.getReadACLs(q1);
|
||||
assertEquals(1, aclsq1.size());
|
||||
assertTrue(aclsq1.contains(new GroupPrincipal("role1")));
|
||||
|
||||
ActiveMQDestination t1 = new ActiveMQTopic("topic1");
|
||||
Set aclst1 = authMap.getReadACLs(t1);
|
||||
assertEquals(1, aclst1.size());
|
||||
assertTrue(aclst1.contains(new GroupPrincipal("role2")));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.activemq.security.LDAPAuthorizationMap.getWriteACLs(ActiveMQDestination)'
|
||||
*/
|
||||
public void testGetWriteACLs() {
|
||||
ActiveMQDestination q1 = new ActiveMQQueue("queue1");
|
||||
Set aclsq1 = authMap.getWriteACLs(q1);
|
||||
assertEquals(2, aclsq1.size());
|
||||
assertTrue(aclsq1.contains(new GroupPrincipal("role1")));
|
||||
assertTrue(aclsq1.contains(new GroupPrincipal("role2")));
|
||||
|
||||
ActiveMQDestination t1 = new ActiveMQTopic("topic1");
|
||||
Set aclst1 = authMap.getWriteACLs(t1);
|
||||
assertEquals(1, aclst1.size());
|
||||
assertTrue(aclst1.contains(new GroupPrincipal("role3")));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
version: 1
|
||||
dn: dc=example,dc=com
|
||||
objectClass: top
|
||||
objectClass: domain
|
||||
objectClass: extensibleObject
|
||||
dc: example
|
||||
|
||||
dn: o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: organization
|
||||
objectclass: top
|
||||
o: ActiveMQ
|
||||
|
||||
dn: ou=users,o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: organizationalUnit
|
||||
objectclass: top
|
||||
ou: users
|
||||
|
||||
dn: uid=ngcutura,ou=users,o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: inetOrgPerson
|
||||
objectclass: organizationalPerson
|
||||
objectclass: person
|
||||
objectclass: top
|
||||
cn: Goran Cutura
|
||||
sn: Cutura
|
||||
uid: ngcutura
|
||||
userpassword:: e3NoYX0wZE9sTGxnU2ZRT3NSaFR5OGx3NUM3K1hlSkE9
|
||||
|
||||
dn: cn=roles,uid=ngcutura,ou=users,o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: groupOfUniqueNames
|
||||
objectclass: top
|
||||
cn: roles
|
||||
uniquemember: aa
|
||||
|
||||
dn: ou=destinations,o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: organizationalUnit
|
||||
objectclass: top
|
||||
ou: destinations
|
||||
|
||||
dn: ou=topics,ou=destinations,o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: organizationalUnit
|
||||
objectclass: top
|
||||
ou: topics
|
||||
|
||||
dn: uid=topic1,ou=topics,ou=destinations,o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: uidObject
|
||||
objectclass: top
|
||||
uid: topic1
|
||||
|
||||
dn: cn=admin,uid=topic1,ou=topics,ou=destinations,o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: groupOfUniqueNames
|
||||
objectclass: top
|
||||
cn: admin
|
||||
uniquemember: role1
|
||||
|
||||
dn: cn=read,uid=topic1,ou=topics,ou=destinations,o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: groupOfUniqueNames
|
||||
objectclass: top
|
||||
cn: read
|
||||
uniquemember: role2
|
||||
|
||||
dn: cn=write,uid=topic1,ou=topics,ou=destinations,o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: groupOfUniqueNames
|
||||
objectclass: top
|
||||
cn: write
|
||||
uniquemember: role3
|
||||
|
||||
dn: ou=queues,ou=destinations,o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: organizationalUnit
|
||||
objectclass: top
|
||||
ou: queues
|
||||
|
||||
dn: uid=queue1,ou=queues,ou=destinations,o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: uidObject
|
||||
objectclass: top
|
||||
uid: queue1
|
||||
|
||||
dn: cn=read,uid=queue1,ou=queues,ou=destinations,o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: groupOfUniqueNames
|
||||
objectclass: top
|
||||
cn: read
|
||||
uniquemember: role1
|
||||
|
||||
dn: cn=write,uid=queue1,ou=queues,ou=destinations,o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: groupOfUniqueNames
|
||||
objectclass: top
|
||||
cn: write
|
||||
uniquemember: role1
|
||||
uniquemember: role2
|
||||
|
||||
dn: cn=admin,uid=queue1,ou=queues,ou=destinations,o=ActiveMQ,dc=example,dc=com
|
||||
objectclass: groupOfUniqueNames
|
||||
objectclass: top
|
||||
cn: admin
|
||||
uniquemember: role1
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
initialContextFactory = com.sun.jndi.ldap.LdapCtxFactory
|
||||
connectionURL = ldap://localhost:10389
|
||||
authentication = simple
|
||||
connectionUsername = uid=admin,ou=system
|
||||
connectionPassword = secret
|
||||
connectionProtocol = s
|
||||
topicSearchMatching = uid={0},ou=topics,ou=destinations,o=ActiveMQ,dc=example,dc=com
|
||||
topicSearchSubtree = true
|
||||
queueSearchMatching = uid={0},ou=queues,ou=destinations,o=ActiveMQ,dc=example,dc=com
|
||||
queueSearchSubtree = true
|
||||
adminBase = (cn=admin)
|
||||
adminAttribute = uniqueMember
|
||||
readBase = (cn=read)
|
||||
readAttribute = uniqueMember
|
||||
writeBAse = (cn=write)
|
||||
writeAttribute = uniqueMember
|
|
@ -0,0 +1,197 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
|
||||
"http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
|
||||
<beans>
|
||||
<bean id="environment" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
|
||||
<property name="properties">
|
||||
<props>
|
||||
<prop key="java.naming.security.authentication">simple</prop>
|
||||
<prop key="java.naming.security.principal">uid=admin,ou=system</prop>
|
||||
<prop key="java.naming.security.credentials">secret</prop>
|
||||
<!--<prop key="kdc.entryBaseDn">ou=users,dc=example,dc=com</prop>-->
|
||||
<!--<prop key="kdc.java.naming.security.credentials">secret</prop>-->
|
||||
<!--<prop key="changepw.entryBaseDn">ou=users,dc=example,dc=com</prop>-->
|
||||
<!--<prop key="changepw.java.naming.security.credentials">secret</prop>-->
|
||||
<!-- Set this key to a space delimited set of attributeType descriptions
|
||||
and their OID's if you want an attributeType to be handled as
|
||||
binary content.
|
||||
|
||||
The server will use the schema to derive the set of attributeTypes
|
||||
to treat as binary. The union if the values you provide here
|
||||
will be taken as the set of binaries. Note to be consistent you
|
||||
must add both the OID and all the names an attributeType can have.
|
||||
-->
|
||||
<!--
|
||||
<prop key="java.naming.ldap.attributes.binary"></prop>
|
||||
-->
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="configuration" class="org.apache.directory.server.core.configuration.MutableStartupConfiguration">
|
||||
<property name="workingDirectory"><value>example.com</value></property>
|
||||
|
||||
<!-- Uncomment below to have the server load entries on startup! -->
|
||||
<!-- ldifDirectory property can point to a relative file, directory or -->
|
||||
<!-- can point to an absolute path to either using the URL path -->
|
||||
<!-- notation: i.e. file:///Users/jack/apacheds/ldifs -->
|
||||
|
||||
<!-- Entries will optionally be filtered using LdifLoadFilters in the -->
|
||||
<!-- order specified. The included Krb5KdcEntryFilter will filter -->
|
||||
<!-- kerberos principals creating keys for them using their -->
|
||||
<!-- userPassword attribute if present. -->
|
||||
|
||||
<!--<property name="ldifDirectory">
|
||||
<value>example.ldif</value>
|
||||
</property>
|
||||
<property name="ldifFilters">
|
||||
<list>
|
||||
<bean class="org.apache.directory.server.protocol.shared.store.Krb5KdcEntryFilter"/>
|
||||
</list>
|
||||
</property>-->
|
||||
|
||||
<property name="allowAnonymousAccess"><value>false</value></property>
|
||||
<property name="accessControlEnabled"><value>false</value></property>
|
||||
<!--
|
||||
<property name="enableNtp"><value>false</value></property>
|
||||
<property name="enableKerberos"><value>false</value></property>
|
||||
<property name="enableChangePassword"><value>false</value></property>
|
||||
<property name="ldapPort"><value>10389</value></property>
|
||||
<property name="contextPartitionConfigurations">
|
||||
<set>
|
||||
<ref bean="examplePartitionConfiguration"/>
|
||||
</set>
|
||||
</property>
|
||||
-->
|
||||
<property name="bootstrapSchemas">
|
||||
<set>
|
||||
<bean class="org.apache.directory.server.core.schema.bootstrap.AutofsSchema"/>
|
||||
<bean class="org.apache.directory.server.core.schema.bootstrap.CorbaSchema"/>
|
||||
<bean class="org.apache.directory.server.core.schema.bootstrap.CoreSchema"/>
|
||||
<bean class="org.apache.directory.server.core.schema.bootstrap.CosineSchema"/>
|
||||
<bean class="org.apache.directory.server.core.schema.bootstrap.ApacheSchema"/>
|
||||
<bean class="org.apache.directory.server.core.schema.bootstrap.CollectiveSchema"/>
|
||||
<bean class="org.apache.directory.server.core.schema.bootstrap.InetorgpersonSchema"/>
|
||||
<bean class="org.apache.directory.server.core.schema.bootstrap.JavaSchema"/>
|
||||
<bean class="org.apache.directory.server.core.schema.bootstrap.Krb5kdcSchema"/>
|
||||
<bean class="org.apache.directory.server.core.schema.bootstrap.NisSchema"/>
|
||||
<bean class="org.apache.directory.server.core.schema.bootstrap.SystemSchema"/>
|
||||
<bean class="org.apache.directory.server.core.schema.bootstrap.ApachednsSchema"/>
|
||||
</set>
|
||||
</property>
|
||||
|
||||
<!--
|
||||
<property name="extendedOperationHandlers">
|
||||
<list>
|
||||
<bean class="org.apache.directory.server.ldap.support.extended.GracefulShutdownHandler"/>
|
||||
<bean class="org.apache.directory.server.ldap.support.extended.LaunchDiagnosticUiHandler"/>
|
||||
</list>
|
||||
</property>
|
||||
|
||||
<property name="interceptorConfigurations">
|
||||
<list>
|
||||
<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
|
||||
<property name="name"><value>normalizationService</value></property>
|
||||
<property name="interceptor">
|
||||
<bean class="org.apache.directory.server.core.normalization.NormalizationService" />
|
||||
</property>
|
||||
</bean>
|
||||
<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
|
||||
<property name="name"><value>authenticationService</value></property>
|
||||
<property name="interceptor">
|
||||
<bean class="org.apache.directory.server.core.authn.AuthenticationService" />
|
||||
</property>
|
||||
</bean>
|
||||
<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
|
||||
<property name="name"><value>referralService</value></property>
|
||||
<property name="interceptor">
|
||||
<bean class="org.apache.directory.server.core.referral.ReferralService" />
|
||||
</property>
|
||||
</bean>
|
||||
<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
|
||||
<property name="name"><value>authorizationService</value></property>
|
||||
<property name="interceptor">
|
||||
<bean class="org.apache.directory.server.core.authz.AuthorizationService" />
|
||||
</property>
|
||||
</bean>
|
||||
<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
|
||||
<property name="name"><value>defaultAuthorizationService</value></property>
|
||||
<property name="interceptor">
|
||||
<bean class="org.apache.directory.server.core.authz.DefaultAuthorizationService" />
|
||||
</property>
|
||||
</bean>
|
||||
<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
|
||||
<property name="name"><value>exceptionService</value></property>
|
||||
<property name="interceptor">
|
||||
<bean class="org.apache.directory.server.core.exception.ExceptionService" />
|
||||
</property>
|
||||
</bean>
|
||||
<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
|
||||
<property name="name"><value>schemaService</value></property>
|
||||
<property name="interceptor">
|
||||
<bean class="org.apache.directory.server.core.schema.SchemaService" />
|
||||
</property>
|
||||
</bean>
|
||||
<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
|
||||
<property name="name"><value>subentryService</value></property>
|
||||
<property name="interceptor">
|
||||
<bean class="org.apache.directory.server.core.subtree.SubentryService" />
|
||||
</property>
|
||||
</bean>
|
||||
<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
|
||||
<property name="name"><value>operationalAttributeService</value></property>
|
||||
<property name="interceptor">
|
||||
<bean class="org.apache.directory.server.core.operational.OperationalAttributeService" />
|
||||
</property>
|
||||
</bean>
|
||||
<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
|
||||
<property name="name"><value>collectiveAttributeService</value></property>
|
||||
<property name="interceptor">
|
||||
<bean class="org.apache.directory.server.core.collective.CollectiveAttributeService" />
|
||||
</property>
|
||||
</bean>
|
||||
<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
|
||||
<property name="name"><value>eventService</value></property>
|
||||
<property name="interceptor">
|
||||
<bean class="org.apache.directory.server.core.event.EventService" />
|
||||
</property>
|
||||
</bean>
|
||||
</list>
|
||||
</property>
|
||||
-->
|
||||
</bean>
|
||||
|
||||
<bean id="examplePartitionConfiguration" class="org.apache.directory.server.core.configuration.MutableDirectoryPartitionConfiguration">
|
||||
<property name="name"><value>example</value></property>
|
||||
<property name="suffix"><value>dc=example,dc=com</value></property>
|
||||
<property name="indexedAttributes">
|
||||
<set>
|
||||
<value>dc</value>
|
||||
<value>ou</value>
|
||||
<value>objectClass</value>
|
||||
<value>krb5PrincipalName</value>
|
||||
<value>uid</value>
|
||||
</set>
|
||||
</property>
|
||||
<property name="contextEntry">
|
||||
<value>
|
||||
objectClass: top
|
||||
objectClass: domain
|
||||
objectClass: extensibleObject
|
||||
dc: example
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
|
||||
<property name="customEditors">
|
||||
<map>
|
||||
<entry key="javax.naming.directory.Attributes">
|
||||
<bean class="org.apache.directory.server.core.configuration.AttributesPropertyEditor"/>
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
</beans>
|
Loading…
Reference in New Issue