Announcement Announcement Module
Collapse
No announcement yet.
Using JmsTemplate to access a secure queue in weblogic 8.1 Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using JmsTemplate to access a secure queue in weblogic 8.1

    Hi,

    Application Setup
    ===========

    I've got a servlet that uses the JmsTemplate to access a ConnectionFactory and a Queue that I've configured in Weblogic's management console. The queue is protected by a security policy.

    I've also got an MDB that receives messages from this queue. The MDB's security identity is set in the ejb-jar.xml and weblogic-ejb-jar.xml and the MDB initialises okay.


    The Problem
    ========

    The problem I'm having is getting the JmsTemplate102 class to send a message to the queue. It keeps throwing a JmsSecurityException when it tries to do this.

    What do I have to do to get the JmsTemplate102 class to pass the security check when sending a message?

    Any help appreciated,

    --Frank

  • #2
    Creating new InitialContext

    Hi,

    It seems that if I create an InitialContext with environment properties including the SECURITY_PRINCIPAL and SECURITY_CREDENTIALS before calling:

    jmsTemplate.send(...)

    then authentication succeeds.

    Code:
    Hashtable props = new Hashtable();
    props.put(Context.SECURITY_PRINCIPAL, "queueUser");
    props.put(Context.SECURITY_CREDENTIALS, "queueUserPassword");
    try {
        Context context = new InitialContext(props);            
    } catch (NamingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    // Now I can make a call to a JMS queue that requires this identity to send messages
    This is, I presume, because the security identity needs to be bound to the current thread.

    I tried adding these properties using the property "jndiEnvironment" on the JndiObjectFactoryBean's that looks up both the connection factory and the queue, but this is done in a different thread (on initialisation), so the identity is never present in calls to jmsTemplate.send(...)

    Does anyone know of a more elegant way of providing SECURITY_PRINCIPAL and SECURITY_CREDENTIALS to a JmsTemplate so that the identity is used when calls to send(...) are made?

    Comment


    • #3
      We probably need a UserCredentialsConnectionFactoryAdapter, similar to our existing UserCredentialsDataSourceAdapter: on a createConnection() call, seamlessly passing specific user credentials to createConnection(username, password). With such a setup, JmsTemplate would implicitly create JMS connections for those user credentials, working with such an adapter for the actual ConnectionFactory as fetched from JNDI.

      Juergen

      Comment


      • #4
        Juergen,

        on a createConnection() call, seamlessly passing specific user credentials to createConnection(username, password)
        I'm not sure that will work - at least not on Weblogic.

        If I don't use a JmsTemplate to create a connection & session, etc, but instead use the straight JNDI approach, then passing in the username and password into the createConnection() function doesn't work on Weblogic 8.

        Only if I create a new context containing the SECURITY_PRINCIPAL and SECURITY_CREDENTIALS properties, does the message get past the authentication process.

        Any thoughts?

        Comment


        • #5
          I tried initializing a context with the props, yet I still can't add a message to the queue. I am using JBoss 3.2.3

          This is the code that does the sending in my ReadyTaskMessageSender:

          Code:
          Hashtable props = new Hashtable();
                  props.put(Context.SECURITY_PRINCIPAL, user);
                  props.put(Context.SECURITY_CREDENTIALS, pwd);
                  try {
                      Context context = new InitialContext(props);
                      
                  } catch (NamingException e) {
                      e.printStackTrace();
                  }
          
                  jt = new JmsTemplate102(connFactory, false);
                  jt.setDestinationResolver(new JndiDestinationResolver());
          
                  jt.send(queue, new MessageCreator()
                  {
                      public Message createMessage(Session session) throws JMSException
                      {
          
                          return session.createObjectMessage(message);
                      }
                  });
          and this is how i configured my JMS


          Code:
          <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
                  <property name="environment">
                      <props>
                          <prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
                          <prop key="java.naming.provider.url">jnp&#58;//localhost&#58;1099</prop>
                          <prop key="java.naming.factory.url.pkgs">org.jboss.naming&#58;org.jnp.interfaces</prop>
                      </props>
                  </property>
              </bean>
          
              <bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
                  <property name="jndiName">
                      <value>java&#58;/ConnectionFactory</value>
                  </property>
                  <property name="jndiTemplate">
                      <ref bean="jndiTemplate"/>
                  </property>
                  <property name="resourceRef">
                      <value>false</value>
                  </property>
              </bean>
          
              <bean id="destination" class="org.springframework.jndi.JndiObjectFactoryBean">
                  <property name="jndiName">
                      <value>queue/ReadyTasksQueue</value>
                  </property>
                  <property name="jndiTemplate">
                      <ref bean="jndiTemplate"/>
                  </property>
                  <property name="resourceRef">
                      <value>false</value>
                  </property>
              </bean>
          
              <bean id="readyTaskMessageSender" class="com.proficiency.messaging.senders.ReadyTaskMessageSender">
                  <property name="connFactory"><ref bean="connectionFactory"/></property>
                  <property name="queue"><ref bean="destination"/></property>
                  <property name="queueUser"><value>me</value></property>
                  <property name="queueUserPassword"><value>12</value></property>
              </bean>

          Comment


          • #6
            Originally posted by Juergen Hoeller
            We probably need a UserCredentialsConnectionFactoryAdapter, similar to our existing UserCredentialsDataSourceAdapter: on a createConnection() call, seamlessly passing specific user credentials to createConnection(username, password). With such a setup, JmsTemplate would implicitly create JMS connections for those user credentials, working with such an adapter for the actual ConnectionFactory as fetched from JNDI.

            Juergen
            Hi Juergen,

            I'm currently trying to connect to a Websphere MQ queue, which requires that I have specify username and password.


            Without using the JmsTemplate I would use
            Code:
             connectionFactory.createConnection(userName, password)
            to connect to the queue. With using the JmsTemplate this is not possible, as the connection is always setup via createConnection(). Therefore I get a JmsSecurityException like described in this post.

            Are there plans to implement the possibity to add username and passwort to the JmsTemplate?

            Are there ways to do it with the current implementation? I do not use JNDI for getting the connection factory, but directly create a object of the MQ connection factory:

            Code:
             <bean id="mqConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
            Thanks in advance.

            Regards,
            Pieper

            Comment


            • #7
              The afformentioned class has been implemented. See the JavaDocs for org.springframework.jms.connection.UserCredentials ConnectionFactoryAdapter. All the details and an example is there.

              Jess

              Comment


              • #8
                Hi Jess,

                thanks for the advice.

                It does work now with using the adapter.

                Pieper

                Comment


                • #9
                  Hi Frank,

                  I've got the same issue than you on Weblogic 9.2, and your workaround also works fine in my case. Thanks !

                  The only problem with the workaround is that the JNDI context is initialized twice, which means bad performance.

                  I'm going to test with Spring 2.0 to see if this issue still exists.

                  Regards,

                  Sven

                  Comment


                  • #10
                    Originally posted by jbalint View Post
                    The afformentioned class has been implemented. See the JavaDocs for org.springframework.jms.connection.UserCredentials ConnectionFactoryAdapter. All the details and an example is there.

                    Jess
                    Thank you. That helped me a lot.

                    Comment


                    • #11
                      Originally posted by sven.gau View Post
                      Hi Frank,

                      I've got the same issue than you on Weblogic 9.2, and your workaround also works fine in my case. Thanks !

                      The only problem with the workaround is that the JNDI context is initialized twice, which means bad performance.

                      I'm going to test with Spring 2.0 to see if this issue still exists.

                      Regards,

                      Sven
                      Hi Sven,

                      Did you find the same problem with Spring 2?

                      I am planning on using Weblogic 9.2 and Spring 2 with the MessageListenerAdapter to simplify development.

                      Comment


                      • #12
                        Access to secure Queues in Jboss 4.0.x with JbossMQ &amp; MySQL 5.x working

                        thanks for this thread everyone. just wanted to let you know i got this working on Jboss 4.0.4 with its default JBossMQ, backed by MySQL.

                        Comment

                        Working...
                        X