/** * 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 javax.jms.Connection; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.Session; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.openmbean.CompositeData; import java.lang.management.ManagementFactory; import java.net.URL; import java.security.Principal; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import junit.framework.Test; import org.apache.activemq.CombinationTestSupport; import org.apache.activemq.broker.Broker; import org.apache.activemq.broker.BrokerPlugin; import org.apache.activemq.broker.BrokerService; import org.apache.activemq.command.ActiveMQQueue; import org.apache.activemq.command.ActiveMQTopic; import org.apache.activemq.filter.DestinationMap; import org.apache.activemq.jaas.GroupPrincipal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Tests that the broker allows/fails access to destinations based on the * security policy installed on the broker. */ public class SimpleSecurityBrokerSystemTest extends SecurityTestSupport { private static final Logger LOG = LoggerFactory.getLogger(SimpleSecurityBrokerSystemTest.class); public static final GroupPrincipal GUESTS = new GroupPrincipal("guests"); public static final GroupPrincipal USERS = new GroupPrincipal("users"); public static final GroupPrincipal ADMINS = new GroupPrincipal("admins"); public static Principal WILDCARD; static { try { WILDCARD = (Principal) DefaultAuthorizationMap.createGroupPrincipal("*", GroupPrincipal.class.getName()); } catch (Exception e) { LOG.error("Failed to make wildcard principal", e); } } public BrokerPlugin authorizationPlugin; public BrokerPlugin authenticationPlugin; static { String path = System.getProperty("java.security.auth.login.config"); if (path == null) { URL resource = SimpleSecurityBrokerSystemTest.class.getClassLoader().getResource("login.config"); if (resource != null) { path = resource.getFile(); System.setProperty("java.security.auth.login.config", path); } } LOG.info("Path to login config: " + path); } public static Test suite() { return suite(SimpleSecurityBrokerSystemTest.class); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } /** * @throws javax.jms.JMSException */ public void testPopulateJMSXUserID() throws Exception { destination = new ActiveMQQueue("TEST"); Connection connection = factory.createConnection("system", "manager"); connections.add(connection); connection.start(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); sendMessages(session, destination, 1); // make sure that the JMSXUserID is exposed over JMX MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); CompositeData[] browse = (CompositeData[]) mbs.invoke(new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost,destinationType=Queue,destinationName=TEST"), "browse", null, null); assertEquals("system", browse[0].get("JMSXUserID")); // And also via JMS. MessageConsumer consumer = session.createConsumer(destination); Message m = consumer.receive(1000); assertTrue(m.propertyExists("JMSXUserID")); assertEquals("system", m.getStringProperty("JMSXUserID")); } public static AuthorizationMap createAuthorizationMap() { DestinationMap readAccess = new DefaultAuthorizationMap(); readAccess.put(new ActiveMQQueue(">"), ADMINS); readAccess.put(new ActiveMQQueue("USERS.>"), USERS); readAccess.put(new ActiveMQQueue("GUEST.>"), GUESTS); readAccess.put(new ActiveMQTopic(">"), ADMINS); readAccess.put(new ActiveMQTopic("USERS.>"), USERS); readAccess.put(new ActiveMQTopic("GUEST.>"), GUESTS); DestinationMap writeAccess = new DefaultAuthorizationMap(); writeAccess.put(new ActiveMQQueue(">"), ADMINS); writeAccess.put(new ActiveMQQueue("USERS.>"), USERS); writeAccess.put(new ActiveMQQueue("GUEST.>"), USERS); writeAccess.put(new ActiveMQQueue("GUEST.>"), GUESTS); writeAccess.put(new ActiveMQTopic(">"), ADMINS); writeAccess.put(new ActiveMQTopic("USERS.>"), USERS); writeAccess.put(new ActiveMQTopic("GUEST.>"), USERS); writeAccess.put(new ActiveMQTopic("GUEST.>"), GUESTS); readAccess.put(new ActiveMQTopic("ActiveMQ.Advisory.>"), WILDCARD); writeAccess.put(new ActiveMQTopic("ActiveMQ.Advisory.>"), WILDCARD); DestinationMap adminAccess = new DefaultAuthorizationMap(); adminAccess.put(new ActiveMQTopic(">"), ADMINS); adminAccess.put(new ActiveMQTopic(">"), USERS); adminAccess.put(new ActiveMQTopic(">"), GUESTS); adminAccess.put(new ActiveMQQueue(">"), ADMINS); adminAccess.put(new ActiveMQQueue(">"), USERS); adminAccess.put(new ActiveMQQueue(">"), GUESTS); return new SimpleAuthorizationMap(writeAccess, readAccess, adminAccess); } public static class SimpleAuthenticationFactory implements BrokerPlugin { @Override public Broker installPlugin(Broker broker) { HashMap<String, String> u = new HashMap<>(); u.put("system", "manager"); u.put("user", "password"); u.put("guest", "password"); Map<String, Set<Principal>> groups = new HashMap<>(); groups.put("system", new HashSet<>(Arrays.asList(new Principal[]{ADMINS, USERS}))); groups.put("user", new HashSet<>(Arrays.asList(new Principal[]{USERS}))); groups.put("guest", new HashSet<>(Arrays.asList(new Principal[]{GUESTS}))); return new SimpleAuthenticationBroker(broker, u, groups); } @Override public String toString() { return "SimpleAuthenticationBroker"; } } /** * @see {@link CombinationTestSupport} */ public void initCombos() { addCombinationValues("authorizationPlugin", new Object[]{new AuthorizationPlugin(createAuthorizationMap())}); addCombinationValues("authenticationPlugin", new Object[]{new SimpleAuthenticationFactory(), new JaasAuthenticationPlugin()}); } @Override protected BrokerService createBroker() throws Exception { BrokerService broker = super.createBroker(); broker.setPopulateJMSXUserID(true); broker.setUseAuthenticatedPrincipalForJMSXUserID(true); broker.setPlugins(new BrokerPlugin[]{authorizationPlugin, authenticationPlugin}); broker.setPersistent(false); return broker; } }