/* * 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.jms.example; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.JMSException; import javax.jms.JMSSecurityException; import javax.jms.MessageConsumer; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TextMessage; import javax.jms.Topic; import javax.naming.InitialContext; public class SecurityExample { public static void main(final String[] args) throws Exception { boolean result = true; Connection failConnection = null; Connection billConnection = null; Connection andrewConnection = null; Connection frankConnection = null; Connection samConnection = null; InitialContext initialContext = null; try { // /Step 1. Create an initial context to perform the JNDI lookup. initialContext = new InitialContext(); // Step 2. perform lookup on the topics Topic genericTopic = (Topic) initialContext.lookup("topic/genericTopic"); Topic europeTopic = (Topic) initialContext.lookup("topic/europeTopic"); Topic usTopic = (Topic) initialContext.lookup("topic/usTopic"); // Step 3. perform a lookup on the Connection Factory ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory"); // Step 4. Try to create a JMS Connection without user/password. It will fail. try { failConnection = cf.createConnection(); result = false; } catch (JMSSecurityException e) { System.out.println("Default user cannot get a connection. Details: " + e.getMessage()); } // Step 5. bill tries to make a connection using wrong password try { billConnection = createConnection("bill", "activemq1", cf); result = false; } catch (JMSException e) { System.out.println("User bill failed to connect. Details: " + e.getMessage()); } // Step 6. bill makes a good connection. billConnection = createConnection("bill", "activemq", cf); billConnection.start(); // Step 7. andrew makes a good connection. andrewConnection = createConnection("andrew", "activemq1", cf); andrewConnection.start(); // Step 8. frank makes a good connection. frankConnection = createConnection("frank", "activemq2", cf); frankConnection.start(); // Step 9. sam makes a good connection. samConnection = createConnection("sam", "activemq3", cf); samConnection.start(); // Step 10. Check every user can publish/subscribe genericTopics. System.out.println("------------------------Checking permissions on " + genericTopic + "----------------"); checkUserSendAndReceive(genericTopic, billConnection, "bill"); checkUserSendAndReceive(genericTopic, andrewConnection, "andrew"); checkUserSendAndReceive(genericTopic, frankConnection, "frank"); checkUserSendAndReceive(genericTopic, samConnection, "sam"); System.out.println("-------------------------------------------------------------------------------------"); System.out.println("------------------------Checking permissions on " + europeTopic + "----------------"); // Step 11. Check permissions on news.europe.europeTopic for bill: can't send and can't receive checkUserNoSendNoReceive(europeTopic, billConnection, "bill"); // Step 12. Check permissions on news.europe.europeTopic for andrew: can send but can't receive checkUserSendNoReceive(europeTopic, andrewConnection, "andrew", frankConnection); // Step 13. Check permissions on news.europe.europeTopic for frank: can't send but can receive checkUserReceiveNoSend(europeTopic, frankConnection, "frank", andrewConnection); // Step 14. Check permissions on news.europe.europeTopic for sam: can't send but can receive checkUserReceiveNoSend(europeTopic, samConnection, "sam", andrewConnection); System.out.println("-------------------------------------------------------------------------------------"); System.out.println("------------------------Checking permissions on " + usTopic + "----------------"); // Step 15. Check permissions on news.us.usTopic for bill: can't send and can't receive checkUserNoSendNoReceive(usTopic, billConnection, "bill"); // Step 16. Check permissions on news.us.usTopic for andrew: can't send and can't receive checkUserNoSendNoReceive(usTopic, andrewConnection, "andrew"); // Step 17. Check permissions on news.us.usTopic for frank: can both send and receive checkUserSendAndReceive(usTopic, frankConnection, "frank"); // Step 18. Check permissions on news.us.usTopic for sam: can't send but can receive checkUserReceiveNoSend(usTopic, samConnection, "sam", frankConnection); System.out.println("-------------------------------------------------------------------------------------"); } finally { // Step 19. Be sure to close our JMS resources! if (failConnection != null) { failConnection.close(); } if (billConnection != null) { billConnection.close(); } if (andrewConnection != null) { andrewConnection.close(); } if (frankConnection != null) { frankConnection.close(); } if (samConnection != null) { samConnection.close(); } // Also the initialContext if (initialContext != null) { initialContext.close(); } } } // Check the user can receive message but cannot send message. private static void checkUserReceiveNoSend(final Topic topic, final Connection connection, final String user, final Connection sendingConn) throws JMSException { Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(topic); MessageConsumer consumer = session.createConsumer(topic); TextMessage msg = session.createTextMessage("hello-world-1"); try { producer.send(msg); throw new IllegalStateException("Security setting is broken! User " + user + " can send message [" + msg.getText() + "] to topic " + topic); } catch (JMSException e) { System.out.println("User " + user + " cannot send message [" + msg.getText() + "] to topic: " + topic); } // Now send a good message Session session1 = sendingConn.createSession(false, Session.AUTO_ACKNOWLEDGE); producer = session1.createProducer(topic); producer.send(msg); TextMessage receivedMsg = (TextMessage) consumer.receive(2000); if (receivedMsg != null) { System.out.println("User " + user + " can receive message [" + receivedMsg.getText() + "] from topic " + topic); } else { throw new IllegalStateException("Security setting is broken! User " + user + " cannot receive message from topic " + topic); } session1.close(); session.close(); } // Check the user can send message but cannot receive message private static void checkUserSendNoReceive(final Topic topic, final Connection connection, final String user, final Connection receivingConn) throws JMSException { Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(topic); try { session.createConsumer(topic); } catch (JMSException e) { System.out.println("User " + user + " cannot receive any message from topic " + topic); } Session session1 = receivingConn.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer goodConsumer = session1.createConsumer(topic); TextMessage msg = session.createTextMessage("hello-world-2"); producer.send(msg); TextMessage receivedMsg = (TextMessage) goodConsumer.receive(2000); if (receivedMsg != null) { System.out.println("User " + user + " can send message [" + receivedMsg.getText() + "] to topic " + topic); } else { throw new IllegalStateException("Security setting is broken! User " + user + " cannot send message [" + msg.getText() + "] to topic " + topic); } session.close(); session1.close(); } // Check the user has neither send nor receive permission on topic private static void checkUserNoSendNoReceive(final Topic topic, final Connection connection, final String user) throws JMSException { Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(topic); try { session.createConsumer(topic); } catch (JMSException e) { System.out.println("User " + user + " cannot create consumer on topic " + topic); } TextMessage msg = session.createTextMessage("hello-world-3"); try { producer.send(msg); throw new IllegalStateException("Security setting is broken! User " + user + " can send message [" + msg.getText() + "] to topic " + topic); } catch (JMSException e) { System.out.println("User " + user + " cannot send message [" + msg.getText() + "] to topic: " + topic); } session.close(); } // Check the user connection has both send and receive permissions on the topic private static void checkUserSendAndReceive(final Topic topic, final Connection connection, final String user) throws JMSException { Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); TextMessage msg = session.createTextMessage("hello-world-4"); MessageProducer producer = session.createProducer(topic); MessageConsumer consumer = session.createConsumer(topic); producer.send(msg); TextMessage receivedMsg = (TextMessage) consumer.receive(5000); if (receivedMsg != null) { System.out.println("User " + user + " can send message: [" + msg.getText() + "] to topic: " + topic); System.out.println("User " + user + " can receive message: [" + msg.getText() + "] from topic: " + topic); } else { throw new IllegalStateException("Error! User " + user + " cannot receive the message! "); } session.close(); } private static Connection createConnection(final String username, final String password, final ConnectionFactory cf) throws JMSException { return cf.createConnection(username, password); } }