Jump to: navigation, search

Stardust/Knowledge Base/Security/JMSCustomization/Queue Security JBoss

Customizing Queues and Connection Factory

This page details the steps to customize Stardust JMS connection factory and JMS queues. The first part of the document deals with enabling queue security using authenticated queue connection factory. The second part details steps to change default Stardust queue names. All the files and artifacts mentioned are available here for your reference.

Platform Used

The customizations are verified on below platform. However, the changes should be easily adaptable to other versions of JBoss and Stardust.

JBoss Application server: jboss-5.1.0.GA
Messaging provider: JBoss default
Stardust: Applicable to all Stardust versions

Enabling Queue Security

This section details the steps needed to enable queue security on Stardust system queues deployed on JBoss application server. The steps mentioned below assume default installation of JBoss and Stardust deployment in spring mode. These steps extend the default setup for creating security credentials and access control definitions.

Understanding default JBoss setup

The default messaging queue security settings for JBoss are defined in the file:

%JBOSS_HOME%\server\default\deploy\messaging\messaging-jboss-beans.xml

The default security config defines following access control on the queues:

       <bean name="SecurityStore" class="org.jboss.jms.server.jbosssx.JBossASSecurityMetadataStore">
        <property name="defaultSecurityConfig">
           <![CDATA[<security>
             <role name="guest" read="true" write="true" create="true"/>
              </security>    ]]>
         </property>
       <property name="securityDomain">messaging</property> ...
...

It defines that a guest user will have full access on the message queues. By default messaging is bound by security domain named “messaging” as seen in the above snippet. This domain is defined in the same file as:

       <application-policy xmlns="urn:jboss:security-beans:1.0" name="messaging">
         <authentication>
            <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
            <module-option name="unauthenticatedIdentity">guest</module-option>
            <module-option name="dsJndiName">java:/DefaultDS</module-option>….
            <module-option name="principalsQuery">SELECT PASSWD FROM JBM_USER WHERE USER_ID=?</module-option>
            <module-option name="rolesQuery">SELECT ROLE_ID, 'Roles' FROM JBM_ROLE WHERE USER_ID=?</module-option>	
.....
...

The above security policy defines that any unauthenticated user will be treated as a guest and the guest user will eventually have full access to the messaging system as defined in the security config.

Stardust system queues use this default security policy. Hence, any user who has required information to connect to the JBoss JNDI context and with the knowledge of Stardust queue names can connect, consume and create messages on these queues. However, security can be enabled on Stardust queues. Following steps will give detailed information on how this can be achieved.

Creating a JMS user

Before we define an access control setting on the queue, we need to create a JMS user. This user will be used by Stardust for creating connections on the queue connection factory. The default JMS user setup is part of this file:

%JBOSS_HOME%\server\default\deploy\messaging\hsqldb-persistence-service.xml

The user database is maintained in an embedded database instance of HSQLDB. The default configuration is as follows:

    <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
      name="jboss.messaging:service=JMSUserManager"
      xmbean-dd="xmdesc/JMSUserManager-xmbean.xml">      
        <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>      
        <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>      
           <attribute name="DataSource">java:/DefaultDS</attribute>      
           <attribute name="CreateTablesOnStartup">true</attribute>      
           <attribute name="SqlProperties"><![CDATA[
POPULATE.TABLES.1  = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('guest', 'guest')
POPULATE.TABLES.2  = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('j2ee', 'j2ee')
POPULATE.TABLES.3  = INSERT INTO JBM_USER (USER_ID, PASSWD, CLIENTID) VALUES ('john', 'needle', 'DurableSubscriberExample')
POPULATE.TABLES.4  = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('nobody', 'nobody')
POPULATE.TABLES.5  = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('dynsub', 'dynsub')
POPULATE.TABLES.6  = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('guest','guest')
POPULATE.TABLES.7  = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('j2ee','guest')

The SQL statements above will create a user and role database each time a server is started. We will create a user for Stardust queues, called “ippuser” and the role will be “ippuser”. Following statements need to be added to the above list:

POPULATE.TABLES.15 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('ippuser','ippuser')

POPULATE.TABLES.16 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('ippuser','ippuser')

Applying access rules for Stardust queues

As mentioned above Stardust queues use the default security configuration for queue access. This configuration can be overridden at each queue level. This configuration is part of this file:

%JBOSS_HOME%\server\default\deploy\ipp-jms-ds.xml

Below we apply a access control policy to the CarnotApplicationQueue:

<mbean code="org.jboss.jms.server.destination.QueueService" 

name="jboss.messaging.destination:service=Queue,name=CarnotApplicationQueue" xmbean-dd="xmdesc/Queue-xmbean.xml">
		<depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
		<depends>jboss.messaging:service=PostOffice</depends>
		<attribute name="JNDIName">queue/CarnotApplicationQueue</attribute>
		<attribute name="RedeliveryDelay">10000</attribute>
		<attribute name="MaxDeliveryAttempts">3</attribute>	
<!—added security config-->	
		<attribute name="SecurityConfig">
			<security>
				<role name="guest" read="false" write="false" create="false"/>
				<role name="ippuser" read="true" write="true" create="true"  />			
			</security>
		</attribute>
	</mbean>

First role element in the security tag defines that a user with role guest will not have any type of access; while the second role element defines that user with role ippuser will have full access to the queue Apply similar security configuration to CarnotSystemQueue and CarnotDaemonQueue.


Once these changes are done, no one will be able to access the queues without authentication. Application would need to supply credentials to authenticate it for queue access.

Supplying credentials for JMS connection factory

With the above changes in place Stardust needs to be configured to supply credentials so that it can get access to the queues. Credentials in terms of user and password should be provided when a queue connection is created from the Carnot connection factory. This can be achieved by providing an adapter connection factory which supplies the configured user credentials to createConnection method of the queue factory. This configuration is part of this file:
%JBOSS_HOME%\server\default\deploy\ipp-portal.war\WEB-INF\config\ipp\spring\carnot-spring-jms-context.xml

Following change needs to be done in this file: Add a user credential connection factory adapter as below. This adapter has user name and password that we created in the steps above.

	<bean id="securedConnectionFactory"
		class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<!—inject instance of the default carnot jms connection factory -->
		<property name="targetConnectionFactory" ref="CarnotJmsConnectionFactory" />
		<property name="username" value="ippuser"/>
		<property name="password" value="ippuser"/>
	</bean>

The instance of securedConnectionFactory should now be injected in place of carnotJmsConnectionFactory in the same file:

	<bean abstract="true" name="AbstractCarnotMessageListenerContainer"
      class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="autoStartup" value="true" />
		<property name="transactionManager" ref="jtaTxManager" />
<!—inject instance of the securedConnectionFactory -->
		<property name="connectionFactory" ref="securedConnectionFactory" />
		<property name="receiveTimeout" value="3000" />
		<property name="sessionTransacted" value="true" />
	</bean>
….
	<bean class="org.eclipse.Stardust.engine.spring.integration.jms.JmsResourceRefBinding">
<property name="name" value="jms/CarnotXAConnectionFactory" />
		<property name="resourceRef" ref="securedConnectionFactory" />
	</bean>

Changing queue names

For production deployment the queue names on the production server might be different than Stardust default names. Hence, a user might have to change the queue names from their defaults. This section of the document details steps of changing the queue names.

Defining queue on the server

Here we define the CarnotSystemQueue differently on the server side. This configuration is part of this file:

%JBOSS_HOME%\server\default\deploy\ipp-jms-ds.xml

We change the name of queue from CarnotSystemQueue to ModifiedCarnotSystemQueue

	<mbean code="org.jboss.jms.server.destination.QueueService" 
name="jboss.messaging.destination:service=Queue,name=CarnotSystemQueue" xmbean-dd="xmdesc/Queue-xmbean.xml">
		<depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
		<depends>jboss.messaging:service=PostOffice</depends>
		<attribute name="JNDIName">queue/ModifiedCarnotSystemQueue</attribute>

Mapping modified server queue within the application

The queue name modified in the above step should now be mapped within the application. Stardust uses class org.springframework.jndi.JndiObjectFactoryBean provided by spring to map JNDI queues to Stardust queues. This configuration is part of this file:

%JBOSS_HOME%\server\default\deploy\carnot-spring-jms-as-context.xml

Following snippet shows the mapping of system queue from the config file:

	<bean name="CarnotJmsSystemQueue"
		class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiName" value="queue/ModifiedCarnotSystemQueue" />
	</bean>