This example shows you how configure and use security with JBoss Messaging.
With security properly configured, JBoss Messaging can restrict client access to its resouces, including connection creation, message sending/receiving, etc. This is done by configuring users and roles as well as permissions in the configuration files.
JBoss Messaging supports wild-card in security configuration. This feature makes security configuration very much flexible and it enables fine-grained control over permissions in an efficient way.
For a full description of how to configure security with JBoss Messaging, please consult the user manual.
This example demonstrates how to configure users/roles, how to configure topics with proper permissions using wild-card expressions, and how they take effects in a simple program.
First we need to configure users with roles. Users and Roles are configured in jbm-users.xml
. This example has four users
configured as below
<user name="bill" password="jbossmessaging">
<role name="user"/>
</user>
<user name="andrew" password="jbossmessaging1">
<role name="europe-user"/>
<role name="user"/>
</user>
<user name="frank" password="jbossmessaging2">
<role name="us-user"/>
<role name="news-user"/>
<role name="user"/>
</user>
<user name="sam" password="jbossmessaging3">
<role name="news-user"/>
<role name="user"/>
</user>
Each user has three properties available: user name, password, and roles it belongs to. It should be noticed that a user can belong to more than one roles. In the above configuration, all users belong to role 'user'. User 'andrew' also belongs to role 'europe-user', user 'frank' also belongs to 'us-user' and 'news-user', and user 'sam' also belongs to 'news-user'.
User name and password consists of a valid account that can be used to establish connections to a JBoss Messaging server, while
roles are used in controling the access privileges against JBoss Messaging topics and queues. You can achieve this control by
configuring proper permissions in jbm-configuration.xml
, like in the following
<security-settings>
<!-- any user can have full control of generic topics -->
<security-setting match="jms.topic.#">
<permission type="createDurableQueue" roles="user"/>
<permission type="deleteDurableQueue" roles="user"/>
<permission type="createTempQueue" roles="user"/>
<permission type="deleteTempQueue" roles="user"/>
<permission type="send" roles="user"/>
<permission type="consume" roles="user"/>
</security-setting>
<security-setting match="jms.topic.news.europe.#">
<permission type="createDurableQueue" roles="user"/>
<permission type="deleteDurableQueue" roles="user"/>
<permission type="createTempQueue" roles="user"/>
<permission type="deleteTempQueue" roles="user"/>
<permission type="send" roles="europe-user"/>
<permission type="consume" roles="news-user"/>
</security-setting>
<security-setting match="jms.topic.news.us.#">
<permission type="createDurableQueue" roles="user"/>
<permission type="deleteDurableQueue" roles="user"/>
<permission type="createTempQueue" roles="user"/>
<permission type="deleteTempQueue" roles="user"/>
<permission type="send" roles="us-user"/>
<permission type="consume" roles="news-user"/>
</security-setting>
</security-settings>
Permissions can be defined on any group of queues, by using a wildcard. You can easily specify wildcards to apply certain permissions to a set of matching queues and topics. In the above configuration we have created four sets of permissions, each set matches against a special group of targets, indicated by wild-card match attributes.
You can provide a very loose permission control for a very general group of destinations. Then you add more strict control over specific topics. By the above we define the following access rules:
To illustrate the effect of permissions, three topics are deployed. Topic 'genericTopic' matches 'jms.topic.#' wild-card, topic 'news.europe.europeTopic' matches jms.topic.news.europe.#' wild-cards, and topic 'news.us.usTopic' matches 'jms.topic.news.us.#'.
With JBoss Messaging, the security manager is also configurable. You can use JAASSecurityManager or JBossASSecurityManager based on you need. Please
check out the jbm-jboss-beans.xml for how to do. In this example we just use the basic JBMSecurityManagerImpl which reads users/roles/passwords from the xml
file jbm-users.xml
.
To run the example, simply type ant
from this directory
client-jndi.properties
file in the directory ../common/config
InitialContext initialContext = getContext(0);
Topic genericTopic = (Topic) initialContext.lookup("/topic/genericTopic");
Topic europeTopic = (Topic) initialContext.lookup("/topic/europeTopic");
Topic usTopic = (Topic) initialContext.lookup("/topic/usTopic");
ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("/ConnectionFactory");
try
{
cf.createConnection();
result = false;
}
catch (JMSSecurityException e)
{
System.out.println("Default user cannot get a connection. Details: " + e.getMessage());
}
billConnection = null;
try
{
billConnection = createConnection("bill", "jbossmessaging1", cf);
result = false;
}
catch (JMSException e)
{
System.out.println("User bill failed to connect. Details: " + e.getMessage());
}
billConnection = createConnection("bill", "jbossmessaging", cf);
billConnection.start();
andrewConnection = createConnection("andrew", "jbossmessaging1", cf);
andrewConnection.start();
frankConnection = createConnection("frank", "jbossmessaging2", cf);
frankConnection.start();
samConnection = createConnection("sam", "jbossmessaging3", cf);
samConnection.start();
checkUserSendAndReceive(genericTopic, billConnection, "bill");
checkUserSendAndReceive(genericTopic, andrewConnection, "andrew");
checkUserSendAndReceive(genericTopic, frankConnection, "frank");
checkUserSendAndReceive(genericTopic, samConnection, "sam");
checkUserNoSendNoReceive(europeTopic, billConnection, "bill", andrewConnection, frankConnection);
checkUserSendNoReceive(europeTopic, andrewConnection, "andrew", frankConnection);
checkUserReceiveNoSend(europeTopic, frankConnection, "frank", andrewConnection);
checkUserReceiveNoSend(europeTopic, samConnection, "sam", andrewConnection);
checkUserNoSendNoReceive(usTopic, billConnection, "bill");
checkUserNoSendNoReceive(usTopic, andrewConnection, "andrew");
checkUserSendAndReceive(usTopic, frankConnection, "frank");
checkUserReceiveNoSend(usTopic, samConnection, "sam", frankConnection);
finally
block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects
finally
{
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();
}
}