Link to home
Start Free TrialLog in
Avatar of cmain
cmain

asked on

JBoss JMS Security Pain!

I am sending a message to a jboss server using the following code.


      private static final String CONNECTION_FACTORY = "UIL2ConnectionFactory";

      Context ctx = new InitialContext();
      Object o = ctx.lookup(CONNECTION_FACTORY);
      
      QueueConnectionFactory factory =
            (QueueConnectionFactory)ctx.lookup(CONNECTION_FACTORY);
      Queue destination = (Queue)ctx.lookup(queueName);
      QueueConnection connection = factory.createQueueConnection();
      QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
      QueueSender sender = session.createSender(destination);
      ObjectMessage message = session.createObjectMessage(msg);
      sender.send(message);
      sender.close();
      session.close();
      connection.close();


My JNDI configuration is as follows.

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=europa:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

This code only works (The message arrives in jboss) if it runs on the local host.
If I execute the same code on a remote machine, pointing to jboss, I get no error, but the message is not delivered.

I tried using "ConnectionFactory" instead of UIL2ConnectionFactory, and got a security exception on one of the remote machines.
I suspect that this is a security issue.

If that is the problem, how do I open up the message bean to the whole planet?
I need to send the message from a remote machine.
Avatar of Tommy Braas
Tommy Braas
Flag of Australia image

It seems that the JNDI configuration is not read on your local machine. Try to use the InitialContext(Hashtable) constructor instead and put your values into a Hashtable and pass it in
Avatar of cmain
cmain

ASKER

You are both incorrect.
I nevertheless tried putting the JNDI properties into the code, with the same result.

The second comment from rama merely explains how to reference beans inside the container. I have already stated that I am trying to connect to the machine from another host. The references are therefore useless to me. I have pasted the full source code below.

Since I do get an exception with the normal connection factory, I suspect that this is all a security issue.

On one of the machines I get the following, no exception message, nothing.
C:\Workflow-Service\svr>java -cp phoenix-util.jar;jbossall-client.jar za.co.pala
ntir.workflow.WorkflowPacket
Properties...
Factory...
Queue...
Session...
Create Object Message...
Sent...

On one of the others I get the following when I use ConnectionFactory instead of UIL2ConnectionFactory.

No Exception message, no message arrives on the queue.
Properties...
Factory...
Queue...
Cannot authenticate user; - nested throwable: (java.net.ConnectException: Connection refused: connect)
org.jboss.mq.SpyJMSException: Cannot authenticate user; - nested throwable: (java.net.ConnectException: Connection refus
ed: connect)
        at org.jboss.mq.Connection.authenticate(Connection.java:883)
        at org.jboss.mq.Connection.<init>(Connection.java:238)
        at org.jboss.mq.Connection.<init>(Connection.java:315)
        at org.jboss.mq.SpyConnection.<init>(SpyConnection.java:60)
        at org.jboss.mq.SpyConnectionFactory.createQueueConnection(SpyConnectionFactory.java:116)
        at za.co.palantir.workflow.WorkflowPacket.send(WorkflowPacket.java:112)
        at za.co.palantir.workflow.WorkflowPacket.main(WorkflowPacket.java:75)
Caused by: java.net.ConnectException: Connection refused: connect
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.PlainSocketImpl.doConnect(Unknown Source)
        at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
        at java.net.PlainSocketImpl.connect(Unknown Source)
        at java.net.Socket.connect(Unknown Source)
        at java.net.Socket.connect(Unknown Source)
        at java.net.Socket.<init>(Unknown Source)
        at java.net.Socket.<init>(Unknown Source)
        at javax.net.DefaultSocketFactory.createSocket(Unknown Source)
        at org.jboss.mq.il.oil.OILServerIL.createConnection(OILServerIL.java:563)
        at org.jboss.mq.il.oil.OILServerIL.checkConnection(OILServerIL.java:507)
        at org.jboss.mq.il.oil.OILServerIL.authenticate(OILServerIL.java:289)
        at org.jboss.mq.Connection.authenticate(Connection.java:876)
        ... 6 more
      public static void send(WorkflowPacket msg, String queueName)
               throws JMSException,
                          NamingException {              

            // Test code
            System.out.println("Properties...");                  
            java.util.Hashtable env = new java.util.Hashtable();
            env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
            env.put(Context.PROVIDER_URL, "europa:1099");
            env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
            Context ctx = new InitialContext(env);
                  //Context ctx = new InitialContext();
            System.out.println("Factory...");
                  Object o = ctx.lookup(CONNECTION_FACTORY);
            
                  QueueConnectionFactory factory =
                        (QueueConnectionFactory)ctx.lookup(CONNECTION_FACTORY);
            System.out.println("Queue...");
                  Queue destination = (Queue)ctx.lookup(queueName);
                  QueueConnection connection = factory.createQueueConnection();            
                  QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
            System.out.println("Session...");
                  QueueSender sender = session.createSender(destination);
                  ObjectMessage message = session.createObjectMessage(msg);
            System.out.println("Create Object Message...");
            sender.send(message);
            System.out.println("Sent...");
                  sender.close();
                  session.close();
                  connection.close();
      }

Which JBoss version is that?
How is the users configured?
Does the exception happens on all machines, or only on one machine, and everything works fine on the other machines?
If it is only on one machine, is it always the same machine, no matter the order which machines runs first?
Avatar of cmain

ASKER

The jboss version is 3.2.2.
There are no users configured, nor do i really want any configured. I want to open the security. I need to test it before I try and add all the security.
And the other questions?
Avatar of cmain

ASKER

Hi,

Further to this, I have discovered that another application was using port 1099 on the source machine.
I have removed this, and now am getting a different error. The machine, even though I can ping it, is not responding.

C:\Workflow-Service\svr>java -cp phoenix-util.jar;jbossall-client.jar;. za.co.pa
lantir.workflow.WorkflowPacket
Properties...
Factory...
Receive timed out
javax.naming.CommunicationException: Receive timed out [Root exception is java.n
et.SocketTimeoutException: Receive timed out]
        at org.jnp.interfaces.NamingContext.discoverServer(NamingContext.java:11
15)
        at org.jnp.interfaces.NamingContext.checkRef(NamingContext.java:1192)
        at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:514)
        at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:507)
        at javax.naming.InitialContext.lookup(Unknown Source)
        at za.co.palantir.workflow.WorkflowPacket.send(WorkflowPacket.java:105)

I am using the following confiugration.
I have tried with ConnectionFactory and UIL2ConnectionFactory


            System.out.println("Properties...");                  
            java.util.Hashtable env = new java.util.Hashtable();
            env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
            env.put(Context.PROVIDER_URL, "10.100.16.123:1099");
            env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
            Context ctx = new InitialContext(env);
                  //Context ctx = new InitialContext();
            System.out.println("Factory...");
      Object o = ctx.lookup(CONNECTION_FACTORY);
            
QueueConnectionFactory factory =
                        (QueueConnectionFactory)ctx.lookup(CONNECTION_FACTORY);
Avatar of cmain

ASKER

I have managed to get it to connect now, but specifiying the IP Address.
I now get authentication errors.

Cannot authenticate user; - nested throwable: (java.net.ConnectException: Connec
tion refused: connect)
org.jboss.mq.SpyJMSException: Cannot authenticate user; - nested throwable: (jav
a.net.ConnectException: Connection refused: connect)
        at org.jboss.mq.Connection.authenticate(Connection.java:883)
        at org.jboss.mq.Connection.<init>(Connection.java:238)
        at org.jboss.mq.Connection.<init>(Connection.java:315)
        at org.jboss.mq.SpyConnection.<init>(SpyConnection.java:60)
        at org.jboss.mq.SpyConnectionFactory.createQueueConnection(SpyConnection
Factory.java:116)
        at za.co.palantir.workflow.WorkflowPacket.send(WorkflowPacket.java:111)
        at za.co.palantir.workflow.WorkflowPacket.main(WorkflowPacket.java:75)
Caused by: java.net.ConnectException: Connection refused: connect
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.PlainSocketImpl.doConnect(Unknown Source)
        at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
        at java.net.PlainSocketImpl.connect(Unknown Source)
        at java.net.Socket.connect(Unknown Source)
        at java.net.Socket.connect(Unknown Source)
        at java.net.Socket.<init>(Unknown Source)
        at java.net.Socket.<init>(Unknown Source)
        at javax.net.DefaultSocketFactory.createSocket(Unknown Source)
        at org.jboss.mq.il.uil2.UILServerIL.createConnection(UILServerIL.java:57
9)
        at org.jboss.mq.il.uil2.UILServerIL.getSocketMgr(UILServerIL.java:500)
        at org.jboss.mq.il.uil2.UILServerIL.authenticate(UILServerIL.java:302)
        at org.jboss.mq.Connection.authenticate(Connection.java:876)
        ... 6 more

C:\Workflow-Service\svr>
So you got back to the original problem? And again, it is on a specific machine?
Avatar of cmain

ASKER

No, not at all.

I am back to the original problem.
My very first assertion was that it was a security problem.

I get the same error from the machines, they cannot authenticate.
If someone has an answer to my orignal question - How do I open up the queue to everyone so that it will work? I will close the question.

Regards
Craig.
I found this on the subject  http://forum.capescience.com/showflat.php?Cat=&Board=webservices&Number=745&page=9&view=collapsed&sb=5&o=&fpart=1

Furthermore, do you nhave the following derfinition in the queue definition in the config file?

 <role name="noacc" read="true" write="true" create="false"/>
Please post your topic/queue definition code. Find it in jbossmq-destinations-service.xml
Avatar of cmain

ASKER

 <mbean code="org.jboss.mq.server.jmx.Queue"
       name="jboss.mq.destination:service=Queue,name=WorkflowMessageEJB">
    <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
    <attribute name="SecurityConf">
      <security>
        <role name="guest" read="true" write="true"/>
        <role name="publisher" read="true" write="true" create="true"/>
        <role name="noacc" read="true" write="true" create="true"/>
      </security>
  </mbean>
 
I have tried it with and without the security information.
Do I have to log in somehow?

I am using a vanilla downloaded jboss 3.2.2 (we have to use 3.2.2 - political reasons).
Maybe there is a bug or something.

What does jms listen on?
Avatar of cmain

ASKER

Hi All,

I have solved the problem for myself.
As it turns out, the bindings on JBoss are screwed up. It really is a mickey mouse application server with buggered documentation.

You need to edit uil2-service.xml, and change the binding address from ${jboss.bind.address} to your IP address. The default binding 0.0.0.0 does not work.
It has nothing to do with authentication. Jboss does not bind to all the interfaces using 0.0.0.0 as it should, and its error handling is so sub standard that it reports network connection errors as authentication errors, or just defaults to the local machine when it cannot connect to the specified remote machine. Quite rediculous, and very annying wild goose chase. At least I learned something about the security.

Regards
Craig.
You should ask for a refund if your points in Community Support since you solved the problem yourself.
ASKER CERTIFIED SOLUTION
Avatar of Netminder
Netminder

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial