diff --git a/artemis-features/src/main/resources/artemis.xml b/artemis-features/src/main/resources/artemis.xml index d99f43de98..99c04a14fa 100644 --- a/artemis-features/src/main/resources/artemis.xml +++ b/artemis-features/src/main/resources/artemis.xml @@ -65,14 +65,14 @@ under the License. - - - - - - + + + + + + - + @@ -85,6 +85,7 @@ under the License. 10485760 10 BLOCK + true diff --git a/artemis-features/src/main/resources/org.apache.activemq.artemis.cfg b/artemis-features/src/main/resources/org.apache.activemq.artemis.cfg index 7714ddf4df..3318d15e45 100644 --- a/artemis-features/src/main/resources/org.apache.activemq.artemis.cfg +++ b/artemis-features/src/main/resources/org.apache.activemq.artemis.cfg @@ -1,3 +1,4 @@ config=file:etc/artemis.xml name=local -domain=local +domain=karaf +rolePrincipalClass=org.apache.karaf.jaas.boot.principal.RolePrincipal diff --git a/artemis-server-osgi/src/main/java/org/apache/activemq/artemis/osgi/OsgiBroker.java b/artemis-server-osgi/src/main/java/org/apache/activemq/artemis/osgi/OsgiBroker.java index d6bfcb8b8e..bfdc73eaa6 100644 --- a/artemis-server-osgi/src/main/java/org/apache/activemq/artemis/osgi/OsgiBroker.java +++ b/artemis-server-osgi/src/main/java/org/apache/activemq/artemis/osgi/OsgiBroker.java @@ -50,6 +50,7 @@ import org.osgi.util.tracker.ServiceTracker; public class OsgiBroker { private String name; private String configurationUrl; + private String rolePrincipalClass; private Map components; private Map> registrations; private ServiceTracker tracker; @@ -60,8 +61,12 @@ public class OsgiBroker { final Dictionary properties = cctx.getProperties(); configurationUrl = getMandatory(properties, "config"); name = getMandatory(properties, "name"); + rolePrincipalClass = (String)properties.get("rolePrincipalClass"); String domain = getMandatory(properties, "domain"); ActiveMQJAASSecurityManager security = new ActiveMQJAASSecurityManager(domain); + if (rolePrincipalClass != null) { + security.setRolePrincipalClass(rolePrincipalClass); + } String brokerInstance = null; String karafDataDir = System.getProperty("karaf.data"); if (karafDataDir != null) { diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQJAASSecurityManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQJAASSecurityManager.java index d0760714b5..ad2a99521e 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQJAASSecurityManager.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQJAASSecurityManager.java @@ -20,6 +20,8 @@ import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import javax.security.cert.X509Certificate; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; import java.security.Principal; import java.util.HashSet; import java.util.Iterator; @@ -45,8 +47,11 @@ public class ActiveMQJAASSecurityManager implements ActiveMQSecurityManager2 { private static final Logger logger = Logger.getLogger(ActiveMQJAASSecurityManager.class); + private static final String WILDCARD = "*"; + private String configurationName; private SecurityConfiguration configuration; + private String rolePrincipalClass = "org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal"; public ActiveMQJAASSecurityManager() { } @@ -72,7 +77,10 @@ public class ActiveMQJAASSecurityManager implements ActiveMQSecurityManager2 { return true; } catch (LoginException e) { - logger.debug("Couldn't validate user", e); + logger.info("Couldn't validate user: " + e.getMessage()); + if (logger.isDebugEnabled()) { + logger.debug("Couldn't validate user", e); + } return false; } } @@ -108,9 +116,15 @@ public class ActiveMQJAASSecurityManager implements ActiveMQSecurityManager2 { Set rolesWithPermission = getPrincipalsInRole(checkType, roles); // Check the caller's roles - Set rolesForSubject = localSubject.getPrincipals(RolePrincipal.class); + Set rolesForSubject = new HashSet(); + try { + rolesForSubject.addAll(localSubject.getPrincipals(Class.forName(rolePrincipalClass).asSubclass(Principal.class))); + } + catch (Exception e) { + logger.info("Can't find roles for the subject", e); + } if (rolesForSubject.size() > 0 && rolesWithPermission.size() > 0) { - Iterator rolesForSubjectIter = rolesForSubject.iterator(); + Iterator rolesForSubjectIter = rolesForSubject.iterator(); while (!authorized && rolesForSubjectIter.hasNext()) { Iterator rolesWithPermissionIter = rolesWithPermission.iterator(); Principal subjectRole = rolesForSubjectIter.next(); @@ -136,10 +150,15 @@ public class ActiveMQJAASSecurityManager implements ActiveMQSecurityManager2 { } private Set getPrincipalsInRole(final CheckType checkType, final Set roles) { - Set principals = new HashSet<>(); + Set principals = new HashSet<>(); for (Role role : roles) { if (checkType.hasRole(role)) { - principals.add(new RolePrincipal(role.getName())); + try { + principals.add(createGroupPrincipal(role.getName(), rolePrincipalClass)); + } + catch (Exception e) { + logger.info("Can't add role principal", e); + } } } return principals; @@ -160,4 +179,71 @@ public class ActiveMQJAASSecurityManager implements ActiveMQSecurityManager2 { return configuration; } + + public String getRolePrincipalClass() { + return rolePrincipalClass; + } + + public void setRolePrincipalClass(String rolePrincipalClass) { + this.rolePrincipalClass = rolePrincipalClass; + } + + public static Object createGroupPrincipal(String name, String groupClass) throws Exception { + if (WILDCARD.equals(name)) { + // simple match all group principal - match any name and class + return new Principal() { + @Override + public String getName() { + return WILDCARD; + } + + @Override + public boolean equals(Object other) { + return true; + } + + @Override + public int hashCode() { + return WILDCARD.hashCode(); + } + }; + } + Object[] param = new Object[]{name}; + + Class cls = Class.forName(groupClass); + + Constructor[] constructors = cls.getConstructors(); + int i; + Object instance; + for (i = 0; i < constructors.length; i++) { + Class[] paramTypes = constructors[i].getParameterTypes(); + if (paramTypes.length != 0 && paramTypes[0].equals(String.class)) { + break; + } + } + if (i < constructors.length) { + instance = constructors[i].newInstance(param); + } + else { + instance = cls.newInstance(); + Method[] methods = cls.getMethods(); + i = 0; + for (i = 0; i < methods.length; i++) { + Class[] paramTypes = methods[i].getParameterTypes(); + if (paramTypes.length != 0 && methods[i].getName().equals("setName") && paramTypes[0].equals(String.class)) { + break; + } + } + + if (i < methods.length) { + methods[i].invoke(instance, param); + } + else { + throw new NoSuchMethodException(); + } + } + + return instance; + } + } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/karaf/ArtemisFeatureTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/karaf/ArtemisFeatureTest.java index e7594cc7aa..b2161101f7 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/karaf/ArtemisFeatureTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/karaf/ArtemisFeatureTest.java @@ -40,6 +40,11 @@ import org.osgi.framework.InvalidSyntaxException; import org.osgi.util.tracker.ServiceTracker; import javax.inject.Inject; +import javax.jms.Connection; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Queue; import javax.security.auth.Subject; import java.io.ByteArrayOutputStream; import java.io.File; @@ -137,13 +142,17 @@ public class ArtemisFeatureTest extends Assert { String amqpURI = "amqp://localhost:5672"; JmsConnectionFactory factory = new JmsConnectionFactory(amqpURI); - factory.setUsername(USER); - factory.setPassword(PASSWORD); + Connection connection = factory.createConnection(USER, PASSWORD); + connection.start(); - //TODO fix security settings and test sending/receiving messages - /* - Connection connection = factory.createConnection(); - connection.start();*/ + javax.jms.Session sess = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE); + Queue queue = sess.createQueue("jms.queue.exampleQueue"); + MessageProducer producer = sess.createProducer(queue); + producer.send(sess.createTextMessage("TEST")); + + MessageConsumer consumer = sess.createConsumer(queue); + Message msg = consumer.receive(5000); + assertNotNull(msg); } protected String executeCommand(final String command, final Long timeout, final Boolean silent) {