When sending a message to a queue in ActiveMQ (e.g. using JmsTemplate.convertAndSend()) that is not configured the queue is dynamically created (on the fly).
Is it possible to have an exception thrown instead (e.g. if the queue wasn't create explicitly on the broker)?
Yes it is possible to have an exception thrown if the queue wasn't create explicitly on the broker. JMS destinations are automatically created for users who have the admin permission. Therefore, any user for which you don't want the broker to automatically create JMS destinations should not be in a role with the admin permission. Here's a sample configuration:
<broker>
..
<plugins>
..
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<authorizationEntry queue="myQueue" read="consumers" write="producers" admin="admins" />
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
..
</plugins>
..
</broker>
In this configuration any users in the admins role will have the admin permission and the broker will automatically create JMS destinations for these users.
Related
Team,
I am implementing runtime reloading of authorization map settings in activemq.xml using following configuration, (http://activemq.apache.org/runtime-configuration.html)
<broker xmlns="http://activemq.apache.org/schema/core" start="false" ... >
<plugins>
<runtimeConfigurationPlugin checkPeriod="1000" />
</plugins>
...
</broker>
I performed test cases out of which one specific case (critical) is not working as expected.
Failed test case is that a User-A has read and write access over Queue-A. User-A successfully reads and writes. But, If the role is deleted for User-A, without restarting ActiveMQ, User-A is still able to read and write to Queue-A. Expected result was that ActiveMQ shall forbid user from reading and writing to Queue-A.
Detailed Steps are as follows.
Action 1 : After starting the broker with a User A without any map entry for test queue
<plugins>
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<authorizationEntry topic="ActiveMQ.Advisory.>" read="admins" write="admins" admin="admins"/>
<authorizationEntry queue="test.queue.A>" read="admins" write="admins" admin="admins"/>
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins>
Result 1: User A login Successful but not authorized to access test queue
Action 2: then I modified the authorization map and allowed user A to read and write on test queue. i.e. made User-A member of "grp_subscribers"
<plugins>
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<authorizationEntry topic="ActiveMQ.Advisory.>" read="grp_subscribers, admins" write="grp_subscribers, admins" admin="grp_subscribers, admins"/>
<authorizationEntry queue="test.queue.A>" read="grp_subscribers" write="grp_subscribers" admin="grp_subscribers, admins"/>
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins>
Result 2: User A login Successful and authorized on test queue
Action 3: then I again modified the authorization map by removing the access of user A on test queue
<plugins>
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<authorizationEntry topic="ActiveMQ.Advisory.>" read="admins" write="admins" admin="admins"/>
<authorizationEntry queue="test.queue.A>" read="admins" write="admins" admin="admins"/>
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins>
Result 3: User A login successful and still authorized on the test queue, which is here the problem is. User A should not be authorized on test queue.
I tried different ways and did a lot of troubleshooting for something if I am missing. I believe there is something I am missing
Activemq AuthorizationMap gets updated using checkPeriod attribute. After making a change in authorization roles, consumer/subscriber/producer connections need to be refreshed, which can be refreshed by stopping or starting a transport connector via jmx.
I have setup an activemq and configured the queue with users. I have created one queue and two users namely producer and consumer with read write permissions appropriately. I am able to post message using producer and consume the message using consumer.
When I login to the admin page of activemq using admin/admin I am not able to view the messages inside the queue. How to add admin user to access the queue.
I have added the below configuration entry in the activemq.xml
<plugins>
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="producer" password="producer" groups="producers" />
<authenticationUser username="consumer" password="consumer" groups="consumers" />
<authenticationUser username="defaultUser" password="defaultPassword" groups="admins" />
</users>
</simpleAuthenticationPlugin>
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<authorizationEntry queue="test.Queue" write="producers" read="consumers" admin="admins" />
<authorizationEntry topic="ActiveMQ.Advisory.>" read="producers,consumers" write="producers,producers" admin="admins,producers,consumers"/>
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins>
Please let me know where I am going wrong.
Your admin user for the web console is in admins group ?
I think you need to add authenticationUser username="admin" password="admin" groups="admins" />
I have a sample Spring application for registering the student. I even created a SQLDB Service using Bluemix. I am unable to bind the service in the spring application in Jpacontext.xml.
If someone could please help me in providing the syntax how to call that would really help me.
The following entries in server.xml enabled me to connect my Spring application to SQLDB Service instance running in Bluemix.
I kept db2jcc4.jar and db2jcc_license_cu.jar in shared/db2 folder.
Please look at the credentials for SQLDB instance in Bluemix to get the database instance name, username, password and host ip address.
<jdbcDriver id="DB2JDBCDriver" libraryRef="DB2"/>
<library id="DB2" name="DB2 Shared Library">
<fileset dir="${shared.resource.dir}/db2" includes="*.jar"/>
</library>
<dataSource id='MyDataSource' beginTranForVendorAPIs="false" jdbcDriverRef="DB2JDBCDriver" jndiName="jdbc/MyDataSource" type="javax.sql.DataSource">
<properties.db2.jcc id='MyDataSource-props' currentLockTimeout="10s"
databaseName='<Database instance name>'
password='<password>'
portNumber='50000'
serverName='<host ip address>'
user='<username>'/>
<connectionManager connectionTimeout="10s" maxConnectionsPerThread="10" maxPoolSize="25" minPoolSize="5"/>
</dataSource>
Hope this helps !
I agree, I think we need more information to be of any real value, however, it may be helpful to begin by reviewing the link below which discusses the SQLDB service
https://www.ng.bluemix.net/docs/services/SQLDB/index.html#cli
and the following link which discusses how to bind to a service in Bluemix.
https://www.ng.bluemix.net/docs/services/reqnsi.html#config
If you still have problems after reviewing this material, then please provide a code snippet and the errors you're encountering.
You may refer to sqldb as JNDI resource. See more details on this here:
https://developer.ibm.com/answers/questions/178223/how-to-connect-to-db2-with-spring/
Taken from the link, example:
datasource-config.xml
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/[some-jndi-name-from-server.xml]" />
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" />
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
<bean id="namedParameterJdbcTemplate"
class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:WEB-INF/datasource-config.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
basically what you need is JNDI name to refer, from server.xml path in your application:
Dashboard -> Your application -> Logs and Files -> app -> .liberty -> usr -> servers -> defaultServer -> server.xml
Than it's possible to refer to your "dataSource" bean in application.
With reference to the ActiveMQ security documentation at http://activemq.apache.org/security.html, I'm trying to add a new user to my ActiveMQ configuration. This user should only be able to see a subset of the available queues.
I have done the following:
1) Added an entry in users.properties:
myuser=mypassword
2) Added an entry in groups.properties:
publishers=admin,myuser
consumers=admin,myuser
3) Added an entry to activemq.xml, in the plugins element of the broker element:
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<authorizationEntry queue=">" read="admins" write="admins" admin="admins" />
<authorizationEntry queue="MYQUEUEPREFIX.>" read="consumers" write="publishers" admin="admins" />
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
When I restart ActiveMQ and access the admin console at myServerURL:8161/admin, I enter the newly created username and password (myuser/mypassword) in the supplied "Authentication required" box but it doesn't give me access to the console. The only way I can get in is by using the already-defined "admin" user.
There is a difference between getting access to ActiveMQ queues via the broker and accessing the ActiveMQ web console. One has to modify the conf/jetty-realm.properties file in order to grant access to the latter.
I have been trying to configure my activemq server so that anonymous clients can just subscribe to topics (they would not be able to create nor publish to topics).
I've set the rights accordingly on my broker configuration:
<plugins>
<simpleAuthenticationPlugin anonymousAccessAllowed="true">
<users>
<authenticationUser username="system" password="manager"
groups="anonymous,admins"/>
</users>
</simpleAuthenticationPlugin>
<!-- Lets configure a destination based authorization mechanism -->
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<authorizationEntry queue=">" read="admins,anonymous" write="admins" admin="admins" />
<authorizationEntry topic=">" read="admins,anonymous" write="admins" admin="admins" />
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins>
and I have been using code below for subscribing based on a couple of tutorials I found on the web. However this topic consumer code, and all the ones I've found, creates an activemq topic to bind to (event if the topic already exists) and as a consequence it will only be authorized if I give admin rights to the user as well... Is there a way to subscribe to the topic without creating it?
ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory(connectionString);
connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = session.createTopic(topicName);
MessageConsumer consumer = null;
consumer = session.createConsumer(destination);
consumer.setMessageListener(this);
connection.start();
The topic has to be created by someone in order to be read from. The alternative to creation of demand is to create the topic through a <destinations> block within the <broker> block:
<destinations>
<topic physicalName="someTopic"/>
</destinations>
When you say "creates an activemq topic to bind to (event if the topic already exists)" you might be seeing advisory topics being created on demand (which is normal). You should add the following to your authorization config:
<authorizationEntry topic="ActiveMQ.Advisory.>"
read="admins"
write="admins,anonymous"
admin="admins,anonymous" />