I have a IBM MQ (v9.2.4.0) running in a Docker container which is configured to work without authentication. However, I’m getting the following error when trying to connect with a MDB:
com.ibm.msg.client.jms.DetailedJMSSecurityException:
JMSWMQ2013: The security authentication was not valid that was supplied for queue manager 'QMGR' with connection mode 'Client' and host name 'queue-test-container(1414)'.
Please check if the supplied username and password are correct on the queue manager to which you are connecting. For further information, review the queue manager error logs and the Securing IBM MQ topic within IBM Documentation.
For completeness, here is its Dockerfile of the IBM MQ:
FROM ibmcom/mq
ENV LICENSE=accept
ENV MQ_QMGR_NAME=QMGR
COPY config.mqsc /etc/mqm/
COPY authentication.mqsc /etc/mqm/
COPY setup.sh /etc/mqm/
USER root
RUN chmod +x /etc/mqm/setup.sh
EXPOSE 1414 9443
CMD ["/etc/mqm/setup.sh"]
with setup.sh
being
#!/bin/bash
# Apply configuration
runmqsc < /etc/mqm/config.mqsc
# Start MQ server
QMGR_NAME=$MQ_QMGR_NAME
strmqm $QMGR_NAME
runmqsc $QMGR_NAME < /etc/mqm/authentication.mqsc
and config.mqsc
being
DEFINE QLOCAL('MY.QUEUE') REPLACE
DEFINE CHANNEL(MY.CHANNEL) +
CHLTYPE(SVRCONN) +
TRPTYPE(TCP) +
MCAUSER('') +
REPLACE
and authentication.mqsc
being
ALTER QMGR CHLAUTH(DISABLED)
This should set up my queue with queue manager QMGR
, channel MY.CHANNEL
, queue MY.QUEUE
and no necessary authentication on port 1414 of my docker container which runs under the name queue-test-container
.
I already confirmed that the queue is up and running and DISPLAY QMGR CHLAUTH CONNAUTH
also confirms that authentication is disabled for QMGR
:
AMQ8408I: Display Queue Manager details.
QMNAME(QMGR) CHLAUTH(DISABLED)
CONNAUTH(DEV.AUTHINFO)
Now I’m having a second Docker container, containing a Java EE app that has a message driven bean connecting to the queue. I configured the MDB as follows:
@MessageDriven(activationConfig = {@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "true"),
@ActivationConfigProperty(propertyName = "connectionNameList", propertyValue = "queue-test-container(1414)"),
@ActivationConfigProperty(propertyName = "queueManager", propertyValue = "QMGR"),
@ActivationConfigProperty(propertyName = "channel", propertyValue = "MY.CHANNEL"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "${jms.dest.queue.request.jndi}"),
@ActivationConfigProperty(propertyName = "transportType", propertyValue = "CLIENT"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")})
@ResourceAdapter(value = "wmq.jmsra.rar")
And finally, here is the IBM MQ configuration in my standalone.xml:
<system-properties>
<property name="jms.queue.container.name" value="queue-test-container"/>
<property name="jms.queue.container.port" value="1414"/>
<property name="jms.connectionfactory.jndi" value="java:/ConnectionFactory"/>
<property name="jms.dest.queue.oneway.jndi" value="java:/queue/importOnewayQueue"/>
<property name="jms.queue.manager.channel" value="MY.CHANNEL"/>
<property name="jms.queue.manager.connectionNameList" value="queue-test-container(1414)"/>
<property name="jms.queue.manager.name" value="QMGR"/>
<property name="com.ibm.mq.cfg.useIBMCipherMappings" value="false"/>
<property name="jms.queue.oneway" value="MY.QUEUE"/>
</system-properties>
...
<subsystem xmlns="urn:jboss:domain:resource-adapters:6.0">
<resource-adapters>
<resource-adapter id="wmq.jmsra.rar">
<archive>
wmq.jmsra.rar
</archive>
<transaction-support>XATransaction</transaction-support>
<config-property name="reconnectionRetryCount">864</config-property>
<connection-definitions>
<connection-definition class-name="com.ibm.mq.connector.outbound.ManagedConnectionFactoryImpl" jndi-name="${jms.connectionfactory.jndi}" use-java-context="false" pool-name="connection-definition">
<config-property name="hostName">${jms.queue.container.name}</config-property>
<config-property name="port">${jms.queue.container.port}</config-property>
<config-property name="queueManager">${jms.queue.manager.name}</config-property>
<config-property name="channel">${jms.queue.manager.channel}</config-property>
<config-property name="transportType">CLIENT</config-property>
<config-property name="connectionNameList">${jms.queue.manager.connectionNameList}</config-property>
<recovery/>
</connection-definition>
</connection-definitions>
<admin-objects>
<admin-object class-name="com.ibm.mq.connector.outbound.MQQueueProxy" jndi-name="${jms.dest.queue.oneway.jndi}" enabled="true" use-java-context="false" pool-name="OnewayQueuePool">
<config-property name="baseQueueName">${jms.queue.oneway}</config-property>
<config-property name="baseQueueManagerName">${jms.queue.manager.name}</config-property>
</admin-object>
</admin-objects>
</resource-adapter>
</resource-adapters>
</subsystem>
Any idea what went wrong? I’m using the version 9.2.4.0 in my pom (the same as my deployed ressource adapter), so it shouldn’t be a version mismatch.
edit: here is the relevant part of my AMQERR01.LOG:
09/05/23 07:54:23 - Process(192.15) User(root) Program(amqzlaa0)
Host(332ec93769f7) Installation(Installation1)
VRMF(9.2.4.0) QMgr(QMGR)
Time(2023-09-05T07:54:23.352Z)
CommentInsert1(jboss)
CommentInsert2(QMGR [qmgr])
CommentInsert3(connect)
AMQ8077W: Entity 'jboss' has insufficient authority to access object QMGR
[qmgr].
EXPLANATION:
The specified entity is not authorized to access the required object. The
following requested permissions are unauthorized: connect
ACTION:
Ensure that the correct level of authority has been set for this entity against
the required object, or ensure that the entity is a member of a privileged
group.
----- amqzfubx.c : 1640 -------------------------------------------------------
09/05/23 07:54:23 - Process(257.5) User(root) Program(amqrmppa)
Host(332ec93769f7) Installation(Installation1)
VRMF(9.2.4.0) QMgr(QMGR)
Time(2023-09-05T07:54:23.352Z)
ArithInsert1(2) ArithInsert2(2035)
CommentInsert1(jboss)
AMQ9557E: Queue Manager User ID initialization failed for 'jboss'.
EXPLANATION:
The call to initialize the User ID 'jboss' failed with CompCode 2 and Reason
2035. If an MQCSP block was used, the User ID in the MQCSP block was ''. If a
userID flow was used, the User ID in the UID header was '' and any CHLAUTH
rules applied prior to user adoption were evaluated case-sensitively against
this value.
ACTION:
Correct the error and try again.
----- cmqxrsrv.c : 2619 -------------------------------------------------------
So I’m reading this that my JBoss container somehow uses "jboss" as a user ID, but I’m not sure how, or why this is a problem here?
2
Answers
The
JMSWMQ2013
error from JMS actually just means that the application received an MQRC_NOT_AUTHORIZED (2035) reason code from MQ. This reason code, deliberately, includes a number of possible failures. To convey the different failures to a client application would enhance the chances of a hacker being able to break in, so very little information is conveyed to the client.To discover the specific reason for the failure, you must inspect the queue manager’s
AMQERR01.LOG
file and see what it is complaining about.You have correctly identified that CHLAUTH is one possibility, but there are numerous others, so take a look and see what it says. If you are unsure after reviewing the error log, please update your question with the error message details and further help will be provided.
You may find the following post useful in the mean time:-
In the following I assume you know that this will not be a suitable production setup. You will need to assure client authentication either by userId/pw check, personal certificates, your own implementation via a security exit or what so ever. I assume you know that switching off userId/pw check means that, well userId and password won’t be checked.
If you don’t want any user ID and password checking at all, then set
CONNAUTH
to blank. Update your version ofauthentication.mqsc
:The refresh is necessary when you alter the connauth parameter and don’t want to restart the Queue Manager.
Alternatively, you can modify the
AUTHINFO
objectDEV.AUTHINFO
or create a new one and use this to specify what authentication you want to take place. But the way I understand your question ("to work without authentication"), the blank value is what you are looking for.However, switching off authentication does not switch off authorization. As
MCAUSER
is blank in your channel definition, it will check authorization for the user which your client sends. As this one is not authenticated, there is no point to grant this specific user.You can switch off authorizations entirely by defining environment variable
MQSNOAUTH
totrue
as described in the MQ doc.Again, be aware of any reasonable warnings about this. And also note, that this does not work for Queue Managers which have already been created before.
If this works for you, you can stop here.
But if you don’t want to switch off authorization entirely with
MQSNOAUTH
, than you can use the following approach to add authorization for all clients which want to connect via your unauthorized channel: Alter your channel definition to add a userId (with the name of your choice) and give this one the required authorizations (for MQ in containers there is no "mqm" super user).Alter the channel def in
config.mqsc
:Again
authentication.mqsc
:AMQERR01.LOG
will tell you, if any authorization is missing.To avoid the need to define a user
myuser
in your container, you can allow MQ to grant authorizations to non-os users. Add a file likeqm-service.ini
to your solution to updateqm.ini
:By the way, you can continue to use this approach when you later on add authentication to your solution by defining an appropriate channel authentication record which overwrites MCAUSER by the authorized userId.