ERROR HQ224018: Failed to create session: HornetQException[errorType=SECURITY_EXCEPTION message=HQ119031: Unable to validate user: null]
When the Jboss EAP 6.3 server is about to receive JMS message. I have the user successfully authenticated by remoting
subsystem so why the user is null? How to overcome this error?
EAP documentation encorage you to:
(...) set allowClientLogin to true (...) If you would like HornetQ to authenticate using the propagated security then set the authoriseOnClientLogin to true also.
But due to HORNETQ-883 bug you have to turn off security for messaging:
<hornetq-server> <!-- … --> <security-enabled>false</security-enabled> <!-- … --> </hornetq-server>
In short, if your JMS client is connecting from within your JEE container and have no need to supply credentials to connect to JMS (when calling factory.createConnection()
), then obtain connections using the InVM
Connector. The InVM Connector doesn't require credentials when opening a connection to JMS (since the caller is within the JVM instance, hence the name) but still enforces security for Remote JMS clients. Connectors and ConnectionFactories are configured in the urn:jboss:domain:messaging
subsystem of standalone.xml
.
Otherwise, if you don't use the InVM Connector with security enabled, you'll probably need to run the add-user
script in [jboss-home]/bin
to add client credentials to the appilcation-users.properties
file and supply those credentials when calling factory.createConnection(username, pwd)
for both Remote and InVM clients connecting via Remotely available factories.
Gory Details
In our JBoss EAP 6.4 instance, security needs to remain enabled for remote connections (outside the JVM) so our <security-settings>
for HornetQ are specified appropriately. Consequently, the JMS ConnectionFactory dictates the level of security based on which Connector it is configured with.
<hornetq-server> <connectors> <!-- additional connectors here --> ... <in-vm-connector name="in-vm" server-id="0"/> </connectors> <jms-connection-factories> <connection-factory name="InVmConnectionFactory"> <connectors> <connector-ref connector-name="in-vm"/> </connectors> <entries> <!-- JNDI bindings here --> <entry name="java:/ConnectionFactory" /> </entries> </connection-factory> ... </jms-connection-factories>
So, in the JMS client apply the standard connection boiler-plate:
InitialContext context = new InitialContext(); javax.jms.ConnectionFactory factory = (ConnectionFactory) context.lookup("java:/ConnectionFactory");
and when creating the connection:
javax.jms.Connection connection = factory.createConnection();
Transacted JMS
For Transaction-aware in-container client connections to JMS, our InVM
ConnectionFactory is configured like this:
<jms-connection-factories> ... <pooled-connection-factory name="hornetq-ra"> <transaction mode="xa"/> <connectors> <connector-ref connector-name="in-vm"/> </connectors> <entries> <entry name="java:/JmsXA"/> </entries> </pooled-connection-factory> </jms-connection-factories>
Obtain the transacted JMS ConnectionFactory as such:
InitialContext context = new InitialContext(); javax.jms.ConnectionFactory factory = (ConnectionFactory) context.lookup("java:/JmsXA");