This closes #325

This commit is contained in:
Clebert Suconic 2016-01-19 09:45:52 -05:00
commit 8e4aca126b
19 changed files with 829 additions and 192 deletions

View File

@ -19,7 +19,6 @@ package org.apache.activemq.artemis.cli.commands;
import java.io.File;
import io.airlift.airline.Command;
import org.apache.activemq.artemis.dto.BrokerDTO;
@Command(name = "stop", description = "stops the broker instance")
public class Stop extends Configurable {
@ -27,9 +26,14 @@ public class Stop extends Configurable {
@Override
public Object execute(ActionContext context) throws Exception {
super.execute(context);
BrokerDTO broker = getBrokerDTO();
File file = broker.server.getConfigurationFile().getParentFile();
String value = getConfiguration();
if (value != null && value.startsWith("xml:")) {
value = value.substring("xml:".length());
}
File file = new File(value).getParentFile();
File stopFile = new File(file, "STOP_ME");

View File

@ -868,6 +868,8 @@ public interface Configuration {
*/
Map<String, Set<Role>> getSecurityRoles();
Configuration putSecurityRoles(String match, Set<Role> roles);
Configuration setConnectorServiceConfigurations(List<ConnectorServiceConfiguration> configs);
Configuration addConnectorServiceConfiguration(ConnectorServiceConfiguration config);

View File

@ -1144,6 +1144,12 @@ public class ConfigurationImpl implements Configuration, Serializable {
return securitySettings;
}
@Override
public ConfigurationImpl putSecurityRoles(String match, Set<Role> roles) {
securitySettings.put(match, roles);
return this;
}
@Override
public ConfigurationImpl setSecurityRoles(final Map<String, Set<Role>> securitySettings) {
this.securitySettings = securitySettings;

View File

@ -541,12 +541,12 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
NodeList list = node.getElementsByTagName(SECURITY_ELEMENT_NAME);
for (int i = 0; i < list.getLength(); i++) {
Pair<String, Set<Role>> securityItem = parseSecurityRoles(list.item(i));
config.getSecurityRoles().put(securityItem.getA(), securityItem.getB());
config.putSecurityRoles(securityItem.getA(), securityItem.getB());
}
list = node.getElementsByTagName(SECURITY_PLUGIN_ELEMENT_NAME);
for (int i = 0; i < list.getLength(); i++) {
Pair<SecuritySettingPlugin, Map<String, String>> securityItem = parseSecuritySettingPlugins(list.item(i));
config.addSecuritySettingPlugin(securityItem.getA().init(securityItem.getB()).populateSecurityRoles());
config.addSecuritySettingPlugin(securityItem.getA().init(securityItem.getB()));
}
}
}

View File

@ -21,6 +21,7 @@ import java.util.Map;
import java.util.Set;
import org.apache.activemq.artemis.core.security.Role;
import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
public interface SecuritySettingPlugin extends Serializable {
/**
@ -35,8 +36,14 @@ public interface SecuritySettingPlugin extends Serializable {
SecuritySettingPlugin init(Map<String, String> options);
/**
* Once {@code #populateSecurityRoles} is invoked this method should return the security role information from the
* external environment (e.g. file, LDAP, etc.).
* Clean up all the associated resources associated with this plugin (e.g. LDAP connections, file handles, etc.)
*
* @return {@code this} instance
*/
SecuritySettingPlugin stop();
/**
* Fetch the security role information from the external environment (e.g. file, LDAP, etc.) and return it.
*
* @return the Map's key corresponds to the "match" for the security setting and the corresponding value is the set of
* {@code org.apache.activemq.artemis.core.security.Role} objects defining the appropriate authorization
@ -44,14 +51,11 @@ public interface SecuritySettingPlugin extends Serializable {
Map<String, Set<Role>> getSecurityRoles();
/**
* Fetch the security role information from the external environment (e.g. file, LDAP, etc.). This method should put
* the security role information in the variable that is returned by {@code #getSecurityRoles()}. This method is
* called by the broker when the file-based configuration is read (see {@code org.apache.activemq.artemis.core.deployers.impl.FileConfigurationParser#parseSecurity(org.w3c.dom.Element, org.apache.activemq.artemis.core.config.Configuration)}
* so that later when {@code #getSecurityRoles()} is called by {@code org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl#deploySecurity()}
* the necessary information will be present. If you're creating/configuring the plugin programmatically then you'll
* want to invoke this method soon after instantiating and configuring it.
* This method is called by the broker during the start-up process. It's for plugins that might need to modify the
* security settings during runtime (e.g. LDAP plugin that uses a listener to receive updates, etc.). Any changes
* made to this {@code HierarchicalRepository} will be reflected in the broker.
*
* @return {@code this} instance
* @param securityRepository
*/
SecuritySettingPlugin populateSecurityRoles();
void setSecurityRepository(HierarchicalRepository<Set<Role>> securityRepository);
}

View File

@ -104,6 +104,7 @@ import org.apache.activemq.artemis.core.server.NodeManager;
import org.apache.activemq.artemis.core.server.Queue;
import org.apache.activemq.artemis.core.server.QueueCreator;
import org.apache.activemq.artemis.core.server.QueueFactory;
import org.apache.activemq.artemis.core.server.SecuritySettingPlugin;
import org.apache.activemq.artemis.core.server.ServerSession;
import org.apache.activemq.artemis.core.server.ServerSessionFactory;
import org.apache.activemq.artemis.core.server.ServiceRegistry;
@ -696,6 +697,10 @@ public class ActiveMQServerImpl implements ActiveMQServer {
stopComponent(memoryManager);
for (SecuritySettingPlugin securitySettingPlugin : configuration.getSecuritySettingPlugins()) {
securitySettingPlugin.stop();
}
if (threadPool != null && !threadPoolSupplied) {
threadPool.shutdown();
try {
@ -1739,6 +1744,10 @@ public class ActiveMQServerImpl implements ActiveMQServer {
for (Map.Entry<String, Set<Role>> entry : configuration.getSecurityRoles().entrySet()) {
securityRepository.addMatch(entry.getKey(), entry.getValue(), true);
}
for (SecuritySettingPlugin securitySettingPlugin : configuration.getSecuritySettingPlugins()) {
securitySettingPlugin.setSecurityRepository(securityRepository);
}
}
private void deployQueuesFromConfiguration() throws Exception {

View File

@ -25,17 +25,25 @@ import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.event.EventDirContext;
import javax.naming.event.NamespaceChangeListener;
import javax.naming.event.NamingEvent;
import javax.naming.event.NamingExceptionEvent;
import javax.naming.event.ObjectChangeListener;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.activemq.artemis.core.security.Role;
import org.apache.activemq.artemis.core.server.SecuritySettingPlugin;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
import org.apache.activemq.artemis.core.server.SecuritySettingPlugin;
import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
private static final long serialVersionUID = 4793109879399750045L;
@ -52,6 +60,7 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
public static final String ADMIN_PERMISSION_VALUE = "adminPermissionValue";
public static final String READ_PERMISSION_VALUE = "readPermissionValue";
public static final String WRITE_PERMISSION_VALUE = "writePermissionValue";
public static final String ENABLE_LISTENER = "enableListener";
private String initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
private String connectionURL = "ldap://localhost:1024";
@ -65,30 +74,43 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
private String adminPermissionValue = "admin";
private String readPermissionValue = "read";
private String writePermissionValue = "write";
private boolean enableListener = true;
private DirContext context;
private Map<String, Set<Role>> securityRoles = new HashMap<>();
private EventDirContext eventContext;
private Map<String, Set<Role>> securityRoles;
private HierarchicalRepository<Set<Role>> securityRepository;
@Override
public LegacyLDAPSecuritySettingPlugin init(Map<String, String> options) {
if (options != null) {
initialContextFactory = options.get(INITIAL_CONTEXT_FACTORY);
connectionURL = options.get(CONNECTION_URL);
connectionUsername = options.get(CONNECTION_USERNAME);
connectionPassword = options.get(CONNECTION_PASSWORD);
connectionProtocol = options.get(CONNECTION_PROTOCOL);
authentication = options.get(AUTHENTICATION);
destinationBase = options.get(DESTINATION_BASE);
filter = options.get(FILTER);
roleAttribute = options.get(ROLE_ATTRIBUTE);
adminPermissionValue = options.get(ADMIN_PERMISSION_VALUE);
readPermissionValue = options.get(READ_PERMISSION_VALUE);
writePermissionValue = options.get(WRITE_PERMISSION_VALUE);
initialContextFactory = getOption(options, INITIAL_CONTEXT_FACTORY, initialContextFactory);
connectionURL = getOption(options, CONNECTION_URL, connectionURL);
connectionUsername = getOption(options, CONNECTION_USERNAME, connectionUsername);
connectionPassword = getOption(options, CONNECTION_PASSWORD, connectionPassword);
connectionProtocol = getOption(options, CONNECTION_PROTOCOL, connectionProtocol);
authentication = getOption(options, AUTHENTICATION, authentication);
destinationBase = getOption(options, DESTINATION_BASE, destinationBase);
filter = getOption(options, FILTER, filter);
roleAttribute = getOption(options, ROLE_ATTRIBUTE, roleAttribute);
adminPermissionValue = getOption(options, ADMIN_PERMISSION_VALUE, adminPermissionValue);
readPermissionValue = getOption(options, READ_PERMISSION_VALUE, readPermissionValue);
writePermissionValue = getOption(options, WRITE_PERMISSION_VALUE, writePermissionValue);
enableListener = getOption(options, ENABLE_LISTENER, Boolean.TRUE.toString()).equalsIgnoreCase(Boolean.TRUE.toString());
}
return this;
}
private String getOption(Map<String, String> options, String key, String defaultValue) {
String result = options.get(key);
if (result == null) {
result = defaultValue;
}
return result;
}
public String getRoleAttribute() {
return roleAttribute;
}
@ -197,11 +219,46 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
return this;
}
protected void open() throws NamingException {
public boolean isEnableListener() {
return enableListener;
}
public LegacyLDAPSecuritySettingPlugin setEnableListener(boolean enableListener) {
this.enableListener = enableListener;
return this;
}
protected boolean isContextAlive() {
boolean alive = false;
if (context != null) {
try {
context.getAttributes("");
alive = true;
}
catch (Exception e) {
}
}
return alive;
}
protected void open() throws NamingException {
if (isContextAlive()) {
return;
}
context = createContext();
eventContext = ((EventDirContext) context.lookup(""));
SearchControls searchControls = new SearchControls();
searchControls.setReturningAttributes(new String[]{roleAttribute});
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
if (enableListener) {
eventContext.addNamingListener(destinationBase, filter, searchControls, new LDAPNamespaceChangeListener());
}
}
private DirContext createContext() throws NamingException {
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
if (connectionUsername != null && !"".equals(connectionUsername)) {
@ -219,16 +276,18 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
env.put(Context.SECURITY_PROTOCOL, connectionProtocol);
env.put(Context.PROVIDER_URL, connectionURL);
env.put(Context.SECURITY_AUTHENTICATION, authentication);
context = new InitialDirContext(env);
return new InitialDirContext(env);
}
@Override
public Map<String, Set<Role>> getSecurityRoles() {
if (securityRoles == null) {
populateSecurityRoles();
}
return securityRoles;
}
@Override
public LegacyLDAPSecuritySettingPlugin populateSecurityRoles() {
private LegacyLDAPSecuritySettingPlugin populateSecurityRoles() {
ActiveMQServerLogger.LOGGER.populatingSecurityRolesFromLDAP(connectionURL);
try {
open();
@ -242,80 +301,240 @@ public class LegacyLDAPSecuritySettingPlugin implements SecuritySettingPlugin {
searchControls.setReturningAttributes(new String[]{roleAttribute});
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
Map<String, Set<Role>> securityRoles = new HashMap<>();
securityRoles = new HashMap<>();
try {
NamingEnumeration<SearchResult> searchResults = context.search(destinationBase, filter, searchControls);
int i = 0;
while (searchResults.hasMore()) {
SearchResult searchResult = searchResults.next();
Attributes attrs = searchResult.getAttributes();
if (attrs == null || attrs.size() == 0) {
continue;
}
LdapName searchResultLdapName = new LdapName(searchResult.getName());
ActiveMQServerLogger.LOGGER.debug("LDAP search result " + ++i + ": " + searchResultLdapName);
String permissionType = null;
String destination = null;
String destinationType = "unknown";
for (Rdn rdn : searchResultLdapName.getRdns()) {
if (rdn.getType().equals("cn")) {
ActiveMQServerLogger.LOGGER.debug("\tPermission type: " + rdn.getValue());
permissionType = rdn.getValue().toString();
}
if (rdn.getType().equals("uid")) {
ActiveMQServerLogger.LOGGER.debug("\tDestination name: " + rdn.getValue());
destination = rdn.getValue().toString();
}
if (rdn.getType().equals("ou")) {
String rawDestinationType = rdn.getValue().toString();
if (rawDestinationType.toLowerCase().contains("queue")) {
destinationType = "queue";
}
else if (rawDestinationType.toLowerCase().contains("topic")) {
destinationType = "topic";
}
ActiveMQServerLogger.LOGGER.debug("\tDestination type: " + destinationType);
}
}
ActiveMQServerLogger.LOGGER.debug("\tAttributes: " + attrs);
Attribute attr = attrs.get(roleAttribute);
NamingEnumeration<?> e = attr.getAll();
Set<Role> roles = securityRoles.get(destination);
boolean exists = false;
if (roles == null) {
roles = new HashSet<>();
}
else {
exists = true;
}
while (e.hasMore()) {
String value = (String) e.next();
LdapName ldapname = new LdapName(value);
Rdn rdn = ldapname.getRdn(ldapname.size() - 1);
String roleName = rdn.getValue().toString();
ActiveMQServerLogger.LOGGER.debug("\tRole name: " + roleName);
Role role = new Role(roleName,
permissionType.equalsIgnoreCase(writePermissionValue),
permissionType.equalsIgnoreCase(readPermissionValue),
permissionType.equalsIgnoreCase(adminPermissionValue),
permissionType.equalsIgnoreCase(adminPermissionValue),
permissionType.equalsIgnoreCase(adminPermissionValue),
permissionType.equalsIgnoreCase(adminPermissionValue),
false); // there is no permission from ActiveMQ 5.x that corresponds to the "manage" permission in ActiveMQ Artemis
roles.add(role);
}
if (!exists) {
securityRoles.put(destination, roles);
}
processSearchResult(securityRoles, searchResults.next());
}
}
catch (Exception e) {
ActiveMQServerLogger.LOGGER.errorPopulatingSecurityRolesFromLDAP(e);
}
this.securityRoles = securityRoles;
return this;
}
@Override
public void setSecurityRepository(HierarchicalRepository<Set<Role>> securityRepository) {
this.securityRepository = securityRepository;
}
private void processSearchResult(Map<String, Set<Role>> securityRoles, SearchResult searchResult) throws NamingException {
Attributes attrs = searchResult.getAttributes();
if (attrs == null || attrs.size() == 0) {
return;
}
LdapName searchResultLdapName = new LdapName(searchResult.getName());
ActiveMQServerLogger.LOGGER.debug("LDAP search result : " + searchResultLdapName);
String permissionType = null;
String destination = null;
String destinationType = "unknown";
for (Rdn rdn : searchResultLdapName.getRdns()) {
if (rdn.getType().equals("cn")) {
ActiveMQServerLogger.LOGGER.debug("\tPermission type: " + rdn.getValue());
permissionType = rdn.getValue().toString();
}
if (rdn.getType().equals("uid")) {
ActiveMQServerLogger.LOGGER.debug("\tDestination name: " + rdn.getValue());
destination = rdn.getValue().toString();
}
if (rdn.getType().equals("ou")) {
String rawDestinationType = rdn.getValue().toString();
if (rawDestinationType.toLowerCase().contains("queue")) {
destinationType = "queue";
}
else if (rawDestinationType.toLowerCase().contains("topic")) {
destinationType = "topic";
}
ActiveMQServerLogger.LOGGER.debug("\tDestination type: " + destinationType);
}
}
ActiveMQServerLogger.LOGGER.debug("\tAttributes: " + attrs);
Attribute attr = attrs.get(roleAttribute);
NamingEnumeration<?> e = attr.getAll();
Set<Role> roles = securityRoles.get(destination);
boolean exists = false;
if (roles == null) {
roles = new HashSet<>();
}
else {
exists = true;
}
while (e.hasMore()) {
String value = (String) e.next();
LdapName ldapname = new LdapName(value);
Rdn rdn = ldapname.getRdn(ldapname.size() - 1);
String roleName = rdn.getValue().toString();
ActiveMQServerLogger.LOGGER.debug("\tRole name: " + roleName);
Role role = new Role(roleName,
permissionType.equalsIgnoreCase(writePermissionValue),
permissionType.equalsIgnoreCase(readPermissionValue),
permissionType.equalsIgnoreCase(adminPermissionValue),
permissionType.equalsIgnoreCase(adminPermissionValue),
permissionType.equalsIgnoreCase(adminPermissionValue),
permissionType.equalsIgnoreCase(adminPermissionValue),
false); // there is no permission from ActiveMQ 5.x that corresponds to the "manage" permission in ActiveMQ Artemis
roles.add(role);
}
if (!exists) {
securityRoles.put(destination, roles);
}
}
public SecuritySettingPlugin stop() {
try {
eventContext.close();
}
catch (NamingException e) {
// ignore
}
try {
context.close();
}
catch (NamingException e) {
// ignore
}
return this;
}
/**
* Handler for new policy entries in the directory.
*
* @param namingEvent
* the new entry event that occurred
*/
public void objectAdded(NamingEvent namingEvent) {
Map<String, Set<Role>> newRoles = new HashMap<>();
try {
processSearchResult(newRoles, (SearchResult) namingEvent.getNewBinding());
for (Map.Entry<String, Set<Role>> entry : newRoles.entrySet()) {
Set<Role> existingRoles = securityRepository.getMatch(entry.getKey());
for (Role role : entry.getValue()) {
existingRoles.add(role);
}
}
}
catch (NamingException e) {
e.printStackTrace();
}
}
/**
* Handler for removed policy entries in the directory.
*
* @param namingEvent
* the removed entry event that occurred
*/
public void objectRemoved(NamingEvent namingEvent) {
try {
LdapName ldapName = new LdapName(namingEvent.getOldBinding().getName());
String match = null;
for (Rdn rdn : ldapName.getRdns()) {
if (rdn.getType().equals("uid")) {
match = rdn.getValue().toString();
}
}
Set<Role> roles = securityRepository.getMatch(match);
List<Role> rolesToRemove = new ArrayList<>();
for (Rdn rdn : ldapName.getRdns()) {
if (rdn.getValue().equals(writePermissionValue)) {
ActiveMQServerLogger.LOGGER.debug("Removing write permission");
for (Role role : roles) {
if (role.isSend()) {
rolesToRemove.add(role);
}
}
}
else if (rdn.getValue().equals(readPermissionValue)) {
ActiveMQServerLogger.LOGGER.debug("Removing read permission");
for (Role role : roles) {
if (role.isConsume()) {
rolesToRemove.add(role);
}
}
}
else if (rdn.getValue().equals(adminPermissionValue)) {
ActiveMQServerLogger.LOGGER.debug("Removing admin permission");
for (Role role : roles) {
if (role.isCreateDurableQueue() || role.isCreateNonDurableQueue() || role.isDeleteDurableQueue() || role.isDeleteNonDurableQueue()) {
rolesToRemove.add(role);
}
}
}
for (Role roleToRemove : rolesToRemove) {
roles.remove(roleToRemove);
}
}
}
catch (NamingException e) {
e.printStackTrace();
}
}
/**
* @param namingEvent
* the renaming entry event that occurred
*/
public void objectRenamed(NamingEvent namingEvent) {
}
/**
* Handler for changed policy entries in the directory.
*
* @param namingEvent
* the changed entry event that occurred
*/
public void objectChanged(NamingEvent namingEvent) {
objectRemoved(namingEvent);
objectAdded(namingEvent);
}
/**
* Handler for exception events from the registry.
*
* @param namingExceptionEvent
* the exception event
*/
public void namingExceptionThrown(NamingExceptionEvent namingExceptionEvent) {
context = null;
ActiveMQServerLogger.LOGGER.error("Caught unexpected exception.", namingExceptionEvent.getException());
}
protected class LDAPNamespaceChangeListener implements NamespaceChangeListener, ObjectChangeListener {
@Override
public void namingExceptionThrown(NamingExceptionEvent evt) {
LegacyLDAPSecuritySettingPlugin.this.namingExceptionThrown(evt);
}
@Override
public void objectAdded(NamingEvent evt) {
LegacyLDAPSecuritySettingPlugin.this.objectAdded(evt);
}
@Override
public void objectRemoved(NamingEvent evt) {
LegacyLDAPSecuritySettingPlugin.this.objectRemoved(evt);
}
@Override
public void objectRenamed(NamingEvent evt) {
LegacyLDAPSecuritySettingPlugin.this.objectRenamed(evt);
}
@Override
public void objectChanged(NamingEvent evt) {
LegacyLDAPSecuritySettingPlugin.this.objectChanged(evt);
}
}
}

View File

@ -698,7 +698,7 @@
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:choice>
<xsd:element name="security-setting" maxOccurs="unbounded" minOccurs="0">
<xsd:complexType>
<xsd:annotation>
@ -735,7 +735,7 @@
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="security-setting-plugin" maxOccurs="unbounded" minOccurs="0">
<xsd:element name="security-setting-plugin" maxOccurs="1" minOccurs="0">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
@ -771,7 +771,7 @@
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
</xsd:element>

View File

@ -16,6 +16,11 @@
*/
package org.apache.activemq.artemis.core.config.impl;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.FileDeploymentManager;
@ -24,11 +29,6 @@ import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.utils.DefaultSensitiveStringCodec;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
public class FileConfigurationParserTest extends ActiveMQTestBase {
/**
@ -43,7 +43,7 @@ public class FileConfigurationParserTest extends ActiveMQTestBase {
*/
@Test
public void testSchemaValidation() throws Exception {
for (int i = 0; i < 6; i++) {
for (int i = 0; i < 7; i++) {
String filename = "InvalidConfigurationTest" + i + ".xml";
FileConfiguration fc = new FileConfiguration();
FileDeploymentManager deploymentManager = new FileDeploymentManager(filename);

View File

@ -24,6 +24,8 @@ import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.activemq.artemis.api.core.BroadcastGroupConfiguration;
import org.apache.activemq.artemis.api.core.DiscoveryGroupConfiguration;
@ -316,13 +318,15 @@ public class FileConfigurationTest extends ConfigurationImplTest {
assertEquals("color='blue'", conf.getQueueConfigurations().get(1).getFilterString());
assertEquals(false, conf.getQueueConfigurations().get(1).isDurable());
assertEquals(2, conf.getSecurityRoles().size());
Map<String, Set<Role>> roles = conf.getSecurityRoles();
assertTrue(conf.getSecurityRoles().containsKey("a1"));
assertEquals(2, roles.size());
assertTrue(conf.getSecurityRoles().containsKey("a2"));
assertTrue(roles.containsKey("a1"));
Role a1Role = conf.getSecurityRoles().get("a1").toArray(new Role[1])[0];
assertTrue(roles.containsKey("a2"));
Role a1Role = roles.get("a1").toArray(new Role[1])[0];
assertFalse(a1Role.isSend());
assertFalse(a1Role.isConsume());
@ -332,7 +336,7 @@ public class FileConfigurationTest extends ConfigurationImplTest {
assertFalse(a1Role.isDeleteNonDurableQueue());
assertFalse(a1Role.isManage());
Role a2Role = conf.getSecurityRoles().get("a2").toArray(new Role[1])[0];
Role a2Role = roles.get("a2").toArray(new Role[1])[0];
assertFalse(a2Role.isSend());
assertFalse(a2Role.isConsume());
@ -341,8 +345,16 @@ public class FileConfigurationTest extends ConfigurationImplTest {
assertFalse(a2Role.isCreateNonDurableQueue());
assertTrue(a2Role.isDeleteNonDurableQueue());
assertFalse(a2Role.isManage());
}
List<SecuritySettingPlugin> securitySettingPlugins = conf.getSecuritySettingPlugins();
@Test
public void testSecuritySettingPlugin() throws Exception {
FileConfiguration fc = new FileConfiguration();
FileDeploymentManager deploymentManager = new FileDeploymentManager("securitySettingPlugin.xml");
deploymentManager.addDeployable(fc);
deploymentManager.readConfiguration();
List<SecuritySettingPlugin> securitySettingPlugins = fc.getSecuritySettingPlugins();
SecuritySettingPlugin securitySettingPlugin = securitySettingPlugins.get(0);
assertTrue(securitySettingPlugin instanceof LegacyLDAPSecuritySettingPlugin);
LegacyLDAPSecuritySettingPlugin legacyLDAPSecuritySettingPlugin = (LegacyLDAPSecuritySettingPlugin) securitySettingPlugin;
@ -358,6 +370,7 @@ public class FileConfigurationTest extends ConfigurationImplTest {
assertEquals(legacyLDAPSecuritySettingPlugin.getAdminPermissionValue(), "testAdminPermissionValue");
assertEquals(legacyLDAPSecuritySettingPlugin.getReadPermissionValue(), "testReadPermissionValue");
assertEquals(legacyLDAPSecuritySettingPlugin.getWritePermissionValue(), "testWritePermissionValue");
assertEquals(legacyLDAPSecuritySettingPlugin.isEnableListener(), false);
}
@Test

View File

@ -232,20 +232,6 @@
<security-setting match="a2">
<permission type="deleteNonDurableQueue" roles="a2.1"/>
</security-setting>
<security-setting-plugin class-name="org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin">
<setting name="initialContextFactory" value="testInitialContextFactory"/>
<setting name="connectionURL" value="testConnectionURL"/>
<setting name="connectionUsername" value="testConnectionUsername"/>
<setting name="connectionPassword" value="testConnectionPassword"/>
<setting name="connectionProtocol" value="testConnectionProtocol"/>
<setting name="authentication" value="testAuthentication"/>
<setting name="destinationBase" value="testDestinationBase"/>
<setting name="filter" value="testFilter"/>
<setting name="roleAttribute" value="testRoleAttribute"/>
<setting name="adminPermissionValue" value="testAdminPermissionValue"/>
<setting name="readPermissionValue" value="testReadPermissionValue"/>
<setting name="writePermissionValue" value="testWritePermissionValue"/>
</security-setting-plugin>
</security-settings>
<address-settings>

View File

@ -0,0 +1,45 @@
<!--
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.
-->
<configuration
xmlns="urn:activemq"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:activemq ../../src/config/common/schema/artemis-server.xsd">
<core xmlns="urn:activemq:core">
<security-settings>
<security-setting match="a1">
<permission type="createNonDurableQueue" roles="a1.1"/>
</security-setting>
<security-setting match="a2">
<permission type="deleteNonDurableQueue" roles="a2.1"/>
</security-setting>
<security-setting-plugin class-name="org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin">
<setting name="initialContextFactory" value="testInitialContextFactory"/>
<setting name="connectionURL" value="testConnectionURL"/>
<setting name="connectionUsername" value="testConnectionUsername"/>
<setting name="connectionPassword" value="testConnectionPassword"/>
<setting name="connectionProtocol" value="testConnectionProtocol"/>
<setting name="authentication" value="testAuthentication"/>
<setting name="destinationBase" value="testDestinationBase"/>
<setting name="filter" value="testFilter"/>
<setting name="roleAttribute" value="testRoleAttribute"/>
<setting name="adminPermissionValue" value="testAdminPermissionValue"/>
<setting name="readPermissionValue" value="testReadPermissionValue"/>
<setting name="writePermissionValue" value="testWritePermissionValue"/>
</security-setting-plugin>
</security-settings>
</core>
</configuration>

View File

@ -0,0 +1,40 @@
<!--
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.
-->
<configuration
xmlns="urn:activemq"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:activemq ../../../../activemq-server/src/main/resources/schema/artemis-server.xsd">
<core xmlns="urn:activemq:core">
<security-settings>
<security-setting-plugin class-name="org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin">
<setting name="initialContextFactory" value="testInitialContextFactory"/>
<setting name="connectionURL" value="testConnectionURL"/>
<setting name="connectionUsername" value="testConnectionUsername"/>
<setting name="connectionPassword" value="testConnectionPassword"/>
<setting name="connectionProtocol" value="testConnectionProtocol"/>
<setting name="authentication" value="testAuthentication"/>
<setting name="destinationBase" value="testDestinationBase"/>
<setting name="filter" value="testFilter"/>
<setting name="roleAttribute" value="testRoleAttribute"/>
<setting name="adminPermissionValue" value="testAdminPermissionValue"/>
<setting name="readPermissionValue" value="testReadPermissionValue"/>
<setting name="writePermissionValue" value="testWritePermissionValue"/>
<setting name="enableListener" value="false"/>
</security-setting-plugin>
</security-settings>
</core>
</configuration>

View File

@ -122,12 +122,10 @@ in sub-groups of addresses.
## Security Setting Plugin
Aside from configuring sets of permissions via XML these permissions can also be
configured via plugins which implement `org.apache.activemq.artemis.core.server.SecuritySettingPlugin`.
One or more plugins can be defined and configured alongside the normal XML, e.g.:
Aside from configuring sets of permissions via XML these permissions can alternatively be
configured via a plugin which implements `org.apache.activemq.artemis.core.server.SecuritySettingPlugin` e.g.:
<security-settings>
...
<security-setting-plugin class-name="org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin">
<setting name="initialContextFactory" value="com.sun.jndi.ldap.LdapCtxFactory"/>
<setting name="connectionURL" value="ldap://localhost:1024"/>
@ -210,6 +208,9 @@ Here is an example of the plugin's configuration:
- `writePermissionValue`. Specifies a value that matches the `write` permission. The default value is `write`.
- `enableListener`. Whether or not to enable a listener that will automatically receive updates made in the LDAP server
and update the broker's authorization configuration in real-time. The default value is `true`.
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. It's worth noting that
since the name of queue or topic coming from LDAP will server as the "match" for the security-setting the security-setting
@ -254,46 +255,12 @@ This is the default security manager.
- The flexible, pluggable `ActiveMQJAASSecurityManager` which supports any standard JAAS login module. Artemis ships
with several login modules which will be discussed further down.
### Non-JAAS Security Manager
If you wish to use the legacy, deprecated `ActiveMQSecurityManager`, then it needs to be added to the `bootstrap.xml`
configuration. Lets take a look at what this might look like:
<basic-security>
<users>file:${activemq.home}/config/non-clustered/artemis-users.properties</users>
<roles>file:${activemq.home}/config/non-clustered/artemis-roles.properties</roles>
<default-user>guest</default-user>
</basic-security>
The first 2 elements `users` and `roles` define what properties files should be used to load in the users and passwords.
The next thing to note is the element `defaultuser`. This defines what user will be assumed when the client does not
specify a username/password when creating a session. In this case they will be the user `guest`. Multiple roles can be
specified for a default user in the `artemis-roles.properties`.
Lets now take a look at the `artemis-users.properties` file, this is basically just a set of key value pairs that define
the users and their password, like so:
bill=activemq
andrew=activemq1
frank=activemq2
sam=activemq3
The `artemis-roles.properties` defines what groups these users belong too where the key is the user and the value is a
comma separated list of the groups the user belongs to, like so:
bill=user
andrew=europe-user,user
frank=us-user,news-user,user
sam=news-user,user
### JAAS Security Manager
When using JAAS much of the configuration depends on which login module is used. However, there are a few commonalities
for every case. Just like in the non-JAAS use-case, the first place to look is in `bootstrap.xml`. Here is an example
using the `PropertiesLogin` JAAS login module which reads user, password, and role information from properties files
much like the non-JAAS security manager implementation:
for every case. The first place to look is in `bootstrap.xml`. Here is an example using the `PropertiesLogin` JAAS login
module which reads user, password, and role information from properties files:
<jaas-security domain="PropertiesLogin"/>

View File

@ -20,10 +20,8 @@ import javax.jms.ConnectionFactory;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.activemq.artemis.api.core.SimpleString;
@ -98,20 +96,13 @@ public class OpenWireTestBase extends ActiveMQTestBase {
//guest cannot do anything
Role destRole = new Role("manager", false, false, false, false, true, true, false);
Map<String, Set<Role>> settings = server.getConfiguration().getSecurityRoles();
if (settings == null) {
settings = new HashMap<>();
server.getConfiguration().setSecurityRoles(settings);
}
Set<Role> anySet = settings.get("#");
if (anySet == null) {
anySet = new HashSet<>();
settings.put("#", anySet);
}
anySet.add(senderRole);
anySet.add(receiverRole);
anySet.add(guestRole);
anySet.add(destRole);
Set<Role> roles = new HashSet<>();
roles.add(senderRole);
roles.add(receiverRole);
roles.add(guestRole);
roles.add(destRole);
server.getConfiguration().putSecurityRoles("#", roles);
}
jmsServer = new JMSServerManagerImpl(server);
namingContext = new InVMNamingContext();

View File

@ -172,7 +172,7 @@ public class LDAPSecurityTest extends AbstractLdapTestUnit {
ActiveMQServer server = getActiveMQServer();
Set<Role> roles = new HashSet<>();
roles.add(new Role("programmers", false, false, false, false, false, false, false));
server.getConfiguration().getSecurityRoles().put("#", roles);
server.getConfiguration().putSecurityRoles("#", roles);
server.start();
server.createQueue(ADDRESS, DURABLE_QUEUE, null, true, false);
server.createQueue(ADDRESS, NON_DURABLE_QUEUE, null, false, false);
@ -260,7 +260,7 @@ public class LDAPSecurityTest extends AbstractLdapTestUnit {
ActiveMQServer server = getActiveMQServer();
Set<Role> roles = new HashSet<>();
roles.add(new Role("admins", true, true, true, true, true, true, true));
server.getConfiguration().getSecurityRoles().put("#", roles);
server.getConfiguration().putSecurityRoles("#", roles);
server.start();
ClientSessionFactory cf = locator.createSessionFactory();

View File

@ -0,0 +1,352 @@
/*
* 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.artemis.tests.integration.security;
import javax.naming.Context;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
import org.apache.activemq.artemis.api.core.client.ClientConsumer;
import org.apache.activemq.artemis.api.core.client.ClientProducer;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory;
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.core.server.impl.LegacyLDAPSecuritySettingPlugin;
import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.directory.server.annotations.CreateLdapServer;
import org.apache.directory.server.annotations.CreateTransport;
import org.apache.directory.server.core.annotations.ApplyLdifFiles;
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
import org.apache.directory.server.core.integ.FrameworkRunner;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
@RunWith(FrameworkRunner.class)
@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP", port = 1024)})
@ApplyLdifFiles("AMQauth.ldif")
public class LegacyLDAPSecuritySettingPluginListenerTest extends AbstractLdapTestUnit {
static {
String path = System.getProperty("java.security.auth.login.config");
if (path == null) {
URL resource = LegacyLDAPSecuritySettingPluginListenerTest.class.getClassLoader().getResource("login.config");
if (resource != null) {
path = resource.getFile();
System.setProperty("java.security.auth.login.config", path);
}
}
}
private ServerLocator locator;
public static final String TARGET_TMP = "./target/tmp";
private static final String PRINCIPAL = "uid=admin,ou=system";
private static final String CREDENTIALS = "secret";
public LegacyLDAPSecuritySettingPluginListenerTest() {
File parent = new File(TARGET_TMP);
parent.mkdirs();
temporaryFolder = new TemporaryFolder(parent);
}
@Rule
public TemporaryFolder temporaryFolder;
private String testDir;
@Before
public void setUp() throws Exception {
locator = ActiveMQClient.createServerLocatorWithHA(new TransportConfiguration(InVMConnectorFactory.class.getCanonicalName()));
testDir = temporaryFolder.getRoot().getAbsolutePath();
}
@SuppressWarnings("unchecked")
@Test
public void testRunning() throws Exception {
DirContext ctx = getContext();
HashSet set = new HashSet();
NamingEnumeration list = ctx.list("ou=system");
while (list.hasMore()) {
NameClassPair ncp = (NameClassPair) list.next();
set.add(ncp.getName());
}
Assert.assertTrue(set.contains("uid=admin"));
Assert.assertTrue(set.contains("ou=users"));
Assert.assertTrue(set.contains("ou=groups"));
Assert.assertTrue(set.contains("ou=configuration"));
Assert.assertTrue(set.contains("prefNodeName=sysPrefRoot"));
}
private DirContext getContext() throws NamingException {
Hashtable env = new Hashtable();
env.put(Context.PROVIDER_URL, "ldap://localhost:1024");
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, PRINCIPAL);
env.put(Context.SECURITY_CREDENTIALS, CREDENTIALS);
return new InitialDirContext(env);
}
@Test
public void testProducerPermissionUpdate() throws Exception {
ActiveMQServer server = getActiveMQServer();
server.getConfiguration().setSecurityInvalidationInterval(0);
server.start();
ClientSessionFactory cf = locator.createSessionFactory();
String name = "queue1";
ClientSession session = cf.createSession("first", "secret", false, true, true, false, 0);
ClientSession session2 = cf.createSession("second", "secret", false, true, true, false, 0);
session.createQueue(SimpleString.toSimpleString(name), SimpleString.toSimpleString(name));
ClientProducer producer = session.createProducer();
ClientProducer producer2 = session2.createProducer();
producer.send(name, session.createMessage(true));
try {
producer2.send(name, session.createMessage(true));
Assert.fail("Sending here should fail due to the original security data.");
}
catch (ActiveMQException e) {
// ok
}
DirContext ctx = getContext();
BasicAttributes basicAttributes = new BasicAttributes();
basicAttributes.put("uniquemember", "uid=role2");
ctx.modifyAttributes("cn=write,uid=queue1,ou=queues,ou=destinations,o=ActiveMQ,ou=system", DirContext.REPLACE_ATTRIBUTE, basicAttributes);
producer2.send(name, session.createMessage(true));
try {
producer.send(name, session.createMessage(true));
Assert.fail("Sending here should fail due to the modified security data.");
}
catch (ActiveMQException e) {
// ok
}
cf.close();
locator.close();
server.stop();
}
@Test
public void testConsumerPermissionUpdate() throws Exception {
ActiveMQServer server = getActiveMQServer();
server.getConfiguration().setSecurityInvalidationInterval(0);
server.start();
ClientSessionFactory cf = locator.createSessionFactory();
String queue = "queue1";
ClientSession session = cf.createSession("first", "secret", false, true, true, false, 0);
ClientSession session2 = cf.createSession("second", "secret", false, true, true, false, 0);
session.createQueue(SimpleString.toSimpleString(queue), SimpleString.toSimpleString(queue));
ClientConsumer consumer = session.createConsumer(queue);
consumer.receiveImmediate();
consumer.close();
ClientConsumer consumer2 = null;
try {
session2.createConsumer(queue);
Assert.fail("Consuming here should fail due to the original security data.");
}
catch (ActiveMQException e) {
// ok
}
DirContext ctx = getContext();
BasicAttributes basicAttributes = new BasicAttributes();
basicAttributes.put("uniquemember", "uid=role2");
ctx.modifyAttributes("cn=read,uid=queue1,ou=queues,ou=destinations,o=ActiveMQ,ou=system", DirContext.REPLACE_ATTRIBUTE, basicAttributes);
consumer2 = session2.createConsumer(queue);
consumer2.receiveImmediate();
consumer2.close();
try {
session.createConsumer(queue);
Assert.fail("Sending here should fail due to the modified security data.");
}
catch (ActiveMQException e) {
// ok
}
cf.close();
locator.close();
server.stop();
}
@Test
public void testNewConsumerPermission() throws Exception {
ActiveMQServer server = getActiveMQServer();
server.getConfiguration().setSecurityInvalidationInterval(0);
server.start();
String queue = "queue2";
server.createQueue(SimpleString.toSimpleString(queue), SimpleString.toSimpleString(queue), null, false, false);
ClientSessionFactory cf = locator.createSessionFactory();
ClientSession session = cf.createSession("first", "secret", false, true, true, false, 0);
ClientConsumer consumer;
try {
session.createConsumer(queue);
Assert.fail("Consuming here should fail due to the original security data.");
}
catch (ActiveMQException e) {
// ok
}
DirContext ctx = getContext();
BasicAttributes basicAttributes = new BasicAttributes();
basicAttributes.put("uniquemember", "uid=role1");
Attribute objclass = new BasicAttribute("objectclass");
objclass.add("top");
objclass.add("groupOfUniqueNames");
basicAttributes.put(objclass);
ctx.bind("cn=read,uid=" + queue + ",ou=queues,ou=destinations,o=ActiveMQ,ou=system", null, basicAttributes);
consumer = session.createConsumer(queue);
consumer.receiveImmediate();
ctx.unbind("cn=read,uid=" + queue + ",ou=queues,ou=destinations,o=ActiveMQ,ou=system");
ctx.close();
try {
session.createConsumer(queue);
Assert.fail("Consuming here should fail due to the modified security data.");
}
catch (ActiveMQException e) {
// ok
}
consumer.close();
cf.close();
locator.close();
server.stop();
}
@Test
public void testNewProducerPermission() throws Exception {
ActiveMQServer server = getActiveMQServer();
server.getConfiguration().setSecurityInvalidationInterval(0);
server.start();
String queue = "queue2";
server.createQueue(SimpleString.toSimpleString(queue), SimpleString.toSimpleString(queue), null, false, false);
ClientSessionFactory cf = locator.createSessionFactory();
ClientSession session = cf.createSession("first", "secret", false, true, true, false, 0);
ClientProducer producer = session.createProducer(SimpleString.toSimpleString(queue));
try {
producer.send(session.createMessage(true));
Assert.fail("Producing here should fail due to the original security data.");
}
catch (ActiveMQException e) {
// ok
}
DirContext ctx = getContext();
BasicAttributes basicAttributes = new BasicAttributes();
basicAttributes.put("uniquemember", "uid=role1");
Attribute objclass = new BasicAttribute("objectclass");
objclass.add("top");
objclass.add("groupOfUniqueNames");
basicAttributes.put(objclass);
ctx.bind("cn=write,uid=" + queue + ",ou=queues,ou=destinations,o=ActiveMQ,ou=system", null, basicAttributes);
producer.send(session.createMessage(true));
ctx.unbind("cn=write,uid=" + queue + ",ou=queues,ou=destinations,o=ActiveMQ,ou=system");
ctx.close();
try {
producer.send(session.createMessage(true));
Assert.fail("Producing here should fail due to the modified security data.");
}
catch (ActiveMQException e) {
// ok
}
producer.close();
cf.close();
locator.close();
server.stop();
}
private ActiveMQServer getActiveMQServer() {
LegacyLDAPSecuritySettingPlugin legacyLDAPSecuritySettingPlugin = new LegacyLDAPSecuritySettingPlugin();
Map<String, String> map = new HashMap<>();
map.put(LegacyLDAPSecuritySettingPlugin.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_URL, "ldap://localhost:1024");
map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_USERNAME, "uid=admin,ou=system");
map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_PASSWORD, "secret");
map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_PROTOCOL, "s");
map.put(LegacyLDAPSecuritySettingPlugin.AUTHENTICATION, "simple");
map.put(LegacyLDAPSecuritySettingPlugin.ENABLE_LISTENER, "true");
legacyLDAPSecuritySettingPlugin.init(map);
// .setInitialContextFactory("com.sun.jndi.ldap.LdapCtxFactory")
// .setConnectionURL("ldap://localhost:1024")
// .setConnectionUsername("uid=admin,ou=system")
// .setConnectionPassword("secret")
// .setConnectionProtocol("s")
// .setAuthentication("simple")
// .setEnableListener(true);
ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager("LDAPLogin");
Configuration configuration = new ConfigurationImpl()
.setSecurityEnabled(true)
.addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getCanonicalName()))
.setJournalDirectory(ActiveMQTestBase.getJournalDir(testDir, 0, false))
.setBindingsDirectory(ActiveMQTestBase.getBindingsDir(testDir, 0, false))
.setPagingDirectory(ActiveMQTestBase.getPageDir(testDir, 0, false))
.setLargeMessagesDirectory(ActiveMQTestBase.getLargeMessagesDir(testDir, 0, false))
.setPersistenceEnabled(false)
.addSecuritySettingPlugin(legacyLDAPSecuritySettingPlugin);
return ActiveMQServers.newActiveMQServer(configuration, ManagementFactory.getPlatformMBeanServer(), securityManager, false);
}
}

View File

@ -297,8 +297,7 @@ public class LegacyLDAPSecuritySettingPluginTest extends AbstractLdapTestUnit {
.setConnectionUsername("uid=admin,ou=system")
.setConnectionPassword("secret")
.setConnectionProtocol("s")
.setAuthentication("simple")
.populateSecurityRoles();
.setAuthentication("simple");
ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager("LDAPLogin");
Configuration configuration = new ConfigurationImpl()

View File

@ -229,7 +229,7 @@ public class SecurityTest extends ActiveMQTestBase {
ActiveMQServer server = addServer(ActiveMQServers.newActiveMQServer(createDefaultInVMConfig().setSecurityEnabled(true), ManagementFactory.getPlatformMBeanServer(), securityManager, false));
Set<Role> roles = new HashSet<>();
roles.add(new Role("programmers", false, false, false, false, false, false, false));
server.getConfiguration().getSecurityRoles().put("#", roles);
server.getConfiguration().putSecurityRoles("#", roles);
server.start();
server.createQueue(ADDRESS, DURABLE_QUEUE, null, true, false);
server.createQueue(ADDRESS, NON_DURABLE_QUEUE, null, false, false);
@ -324,7 +324,7 @@ public class SecurityTest extends ActiveMQTestBase {
Set<Role> roles = new HashSet<>();
roles.add(new Role("programmers", false, false, false, false, false, false, false));
server.getConfiguration().getSecurityRoles().put("#", roles);
server.getConfiguration().putSecurityRoles("#", roles);
server.start();
@ -418,7 +418,7 @@ public class SecurityTest extends ActiveMQTestBase {
ActiveMQServer server = addServer(ActiveMQServers.newActiveMQServer(createDefaultInVMConfig().setSecurityEnabled(true), ManagementFactory.getPlatformMBeanServer(), securityManager, false));
Set<Role> roles = new HashSet<>();
roles.add(new Role("programmers", true, true, true, true, true, true, true));
server.getConfiguration().getSecurityRoles().put("#", roles);
server.getConfiguration().putSecurityRoles("#", roles);
server.start();
ClientSessionFactory cf = createSessionFactory(locator);
@ -506,7 +506,7 @@ public class SecurityTest extends ActiveMQTestBase {
Set<Role> roles = new HashSet<>();
roles.add(new Role("programmers", true, true, true, true, true, true, true));
server.getConfiguration().getSecurityRoles().put("#", roles);
server.getConfiguration().putSecurityRoles("#", roles);
server.start();
TransportConfiguration tc = new TransportConfiguration(NETTY_CONNECTOR_FACTORY);
@ -590,7 +590,7 @@ public class SecurityTest extends ActiveMQTestBase {
ActiveMQServer server = addServer(ActiveMQServers.newActiveMQServer(createDefaultInVMConfig().setSecurityEnabled(true), ManagementFactory.getPlatformMBeanServer(), securityManager, false));
Set<Role> roles = new HashSet<>();
roles.add(new Role("bar", true, true, true, true, true, true, true));
server.getConfiguration().getSecurityRoles().put("#", roles);
server.getConfiguration().putSecurityRoles("#", roles);
server.start();
ClientSessionFactory cf = createSessionFactory(locator);