ARTEMIS-2889 better support for JMS topics with legacy LDAP plugin
This commit is contained in:
parent
400623afcb
commit
9a90248f49
|
@ -66,6 +66,7 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
|
|||
public static final String WRITE_PERMISSION_VALUE = "writePermissionValue";
|
||||
public static final String ENABLE_LISTENER = "enableListener";
|
||||
public static final String MAP_ADMIN_TO_MANAGE = "mapAdminToManage";
|
||||
public static final String ALLOW_QUEUE_ADMIN_ON_READ = "allowQueueAdminOnRead";
|
||||
|
||||
private String initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
|
||||
private String connectionURL = "ldap://localhost:1024";
|
||||
|
@ -81,6 +82,7 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
|
|||
private String writePermissionValue = "write";
|
||||
private boolean enableListener = true;
|
||||
private boolean mapAdminToManage = false;
|
||||
private boolean allowQueueAdminOnRead = false;
|
||||
|
||||
private DirContext context;
|
||||
private EventDirContext eventContext;
|
||||
|
@ -104,6 +106,7 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
|
|||
writePermissionValue = getOption(options, WRITE_PERMISSION_VALUE, writePermissionValue);
|
||||
enableListener = getOption(options, ENABLE_LISTENER, Boolean.TRUE.toString()).equalsIgnoreCase(Boolean.TRUE.toString());
|
||||
mapAdminToManage = getOption(options, MAP_ADMIN_TO_MANAGE, Boolean.FALSE.toString()).equalsIgnoreCase(Boolean.TRUE.toString());
|
||||
allowQueueAdminOnRead = getOption(options, ALLOW_QUEUE_ADMIN_ON_READ, Boolean.FALSE.toString()).equalsIgnoreCase(Boolean.TRUE.toString());
|
||||
}
|
||||
|
||||
return this;
|
||||
|
@ -244,6 +247,15 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
|
|||
return this;
|
||||
}
|
||||
|
||||
public boolean isAllowQueueAdminOnRead() {
|
||||
return allowQueueAdminOnRead;
|
||||
}
|
||||
|
||||
public LegacyLDAPSecuritySettingPlugin setAllowQueueAdminOnRead(boolean allowQueueAdminOnRead) {
|
||||
this.allowQueueAdminOnRead = allowQueueAdminOnRead;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected boolean isContextAlive() {
|
||||
boolean alive = false;
|
||||
if (context != null) {
|
||||
|
@ -405,18 +417,20 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
|
|||
if (logger.isDebugEnabled()) {
|
||||
logMessage.append("\n\tRole name: ").append(roleName);
|
||||
}
|
||||
boolean write = permissionType.equalsIgnoreCase(writePermissionValue);
|
||||
boolean read = permissionType.equalsIgnoreCase(readPermissionValue);
|
||||
boolean admin = permissionType.equalsIgnoreCase(adminPermissionValue);
|
||||
Role role = new Role(roleName,
|
||||
permissionType.equalsIgnoreCase(writePermissionValue), // send
|
||||
permissionType.equalsIgnoreCase(readPermissionValue), // consume
|
||||
permissionType.equalsIgnoreCase(adminPermissionValue), // createDurableQueue
|
||||
permissionType.equalsIgnoreCase(adminPermissionValue), // deleteDurableQueue
|
||||
permissionType.equalsIgnoreCase(adminPermissionValue), // createNonDurableQueue
|
||||
permissionType.equalsIgnoreCase(adminPermissionValue), // deleteNonDurableQueue
|
||||
mapAdminToManage ? permissionType.equalsIgnoreCase(adminPermissionValue) : false, // manage - map to admin based on configuration
|
||||
permissionType.equalsIgnoreCase(readPermissionValue), // browse
|
||||
permissionType.equalsIgnoreCase(adminPermissionValue), // createAddress
|
||||
permissionType.equalsIgnoreCase(adminPermissionValue) // deleteAddress
|
||||
);
|
||||
write, // send
|
||||
read, // consume
|
||||
(allowQueueAdminOnRead && read) || admin, // createDurableQueue
|
||||
(allowQueueAdminOnRead && read) || admin, // deleteDurableQueue
|
||||
(allowQueueAdminOnRead && read) || admin, // createNonDurableQueue
|
||||
admin, // deleteNonDurableQueue
|
||||
mapAdminToManage ? admin : false, // manage - map to admin based on configuration
|
||||
read, // browse
|
||||
admin, // createAddress
|
||||
admin); // deleteAddress
|
||||
roles.add(role);
|
||||
}
|
||||
|
||||
|
|
|
@ -300,6 +300,12 @@ and Security Layer (SASL) authentication is currently not supported.
|
|||
`manage` permission. See details of the mapping semantics below. The default
|
||||
value is `false`.
|
||||
|
||||
- `allowQueueAdminOnRead`. Whether or not to map the legacy `read` permission to
|
||||
the `createDurableQueue`, `createNonDurableQueue`, and `deleteDurableQueue`
|
||||
permissions so that JMS clients can create durable and non-durable subscriptions
|
||||
without needing the `admin` permission. This was allowed in ActiveMQ 5.x. The
|
||||
default value is `false`.
|
||||
|
||||
The name of the queue or topic defined in LDAP will serve as the "match" for
|
||||
the security-setting, the permission value will be mapped from the ActiveMQ 5.x
|
||||
type to the Artemis type, and the role will be mapped as-is.
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
*/
|
||||
package org.apache.activemq.artemis.tests.integration.security;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.ConnectionFactory;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.Topic;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NameClassPair;
|
||||
import javax.naming.NamingEnumeration;
|
||||
|
@ -44,7 +49,9 @@ import org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory;
|
|||
import org.apache.activemq.artemis.core.server.ActiveMQServer;
|
||||
import org.apache.activemq.artemis.core.server.ActiveMQServers;
|
||||
import org.apache.activemq.artemis.api.core.RoutingType;
|
||||
import org.apache.activemq.artemis.core.server.impl.AddressInfo;
|
||||
import org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin;
|
||||
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
|
||||
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
|
||||
import org.apache.directory.server.annotations.CreateLdapServer;
|
||||
|
@ -320,4 +327,38 @@ public class LegacyLDAPSecuritySettingPluginTest extends AbstractLdapTestUnit {
|
|||
session.close();
|
||||
cf.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJmsTopicSubscriberReadPermissionOnly() throws Exception {
|
||||
internalJmsTopicSubscriberReadPermissionOnly(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJmsTopicDurableSubscriberReadPermissionOnly() throws Exception {
|
||||
internalJmsTopicSubscriberReadPermissionOnly(true);
|
||||
}
|
||||
|
||||
private void internalJmsTopicSubscriberReadPermissionOnly(boolean durable) throws Exception {
|
||||
((LegacyLDAPSecuritySettingPlugin)server.getConfiguration().getSecuritySettingPlugins().get(0)).setAllowQueueAdminOnRead(true);
|
||||
server.start();
|
||||
|
||||
// The address needs to exist already otherwise the "admin" permission is required to create it
|
||||
server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString("topic1"), RoutingType.MULTICAST));
|
||||
|
||||
ConnectionFactory cf = new ActiveMQConnectionFactory("vm://0");
|
||||
try (Connection connection = cf.createConnection("third", "secret")) {
|
||||
Session session = connection.createSession();
|
||||
Topic topic = session.createTopic("topic1");
|
||||
if (durable) {
|
||||
MessageConsumer consumer = session.createSharedDurableConsumer(topic, "foo");
|
||||
consumer.close();
|
||||
session.unsubscribe("foo");
|
||||
} else {
|
||||
session.createConsumer(topic);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail("should not throw exception here");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,13 @@ objectClass: account
|
|||
objectClass: simpleSecurityObject
|
||||
objectClass: top
|
||||
|
||||
dn: uid=third,ou=system
|
||||
uid: third
|
||||
userPassword: secret
|
||||
objectClass: account
|
||||
objectClass: simpleSecurityObject
|
||||
objectClass: top
|
||||
|
||||
dn: cn=role1,ou=system
|
||||
cn: role1
|
||||
member: uid=first,ou=system
|
||||
|
@ -51,6 +58,12 @@ member: uid=second,ou=system
|
|||
objectClass: groupOfNames
|
||||
objectClass: top
|
||||
|
||||
dn: cn=role3,ou=system
|
||||
cn: role3
|
||||
member: uid=third,ou=system
|
||||
objectClass: groupOfNames
|
||||
objectClass: top
|
||||
|
||||
dn: ou=destinations,o=ActiveMQ,ou=system
|
||||
objectclass: organizationalUnit
|
||||
objectclass: top
|
||||
|
@ -61,6 +74,11 @@ objectclass: organizationalUnit
|
|||
objectclass: top
|
||||
ou: queues
|
||||
|
||||
dn: ou=topics,ou=destinations,o=ActiveMQ,ou=system
|
||||
objectclass: organizationalUnit
|
||||
objectclass: top
|
||||
ou: topics
|
||||
|
||||
dn: cn=queue1,ou=queues,ou=destinations,o=ActiveMQ,ou=system
|
||||
objectclass: applicationProcess
|
||||
objectclass: top
|
||||
|
@ -71,6 +89,11 @@ objectclass: applicationProcess
|
|||
objectclass: top
|
||||
cn: queue2
|
||||
|
||||
dn: cn=topic1,ou=topics,ou=destinations,o=ActiveMQ,ou=system
|
||||
objectclass: applicationProcess
|
||||
objectclass: top
|
||||
cn: topic1
|
||||
|
||||
dn: cn=activemq.management,ou=queues,ou=destinations,o=ActiveMQ,ou=system
|
||||
objectclass: applicationProcess
|
||||
objectclass: top
|
||||
|
@ -112,6 +135,12 @@ objectclass: top
|
|||
cn: admin
|
||||
uniquemember: cn=role1
|
||||
|
||||
dn: cn=read,cn=topic1,ou=topics,ou=destinations,o=ActiveMQ,ou=system
|
||||
objectclass: groupOfUniqueNames
|
||||
objectclass: top
|
||||
cn: read
|
||||
uniquemember: cn=role3
|
||||
|
||||
## group with member identified just by DN from SASL external tls certificate subject DN
|
||||
dn: cn=widgets,ou=system
|
||||
cn: widgets
|
||||
|
|
Loading…
Reference in New Issue