1

我需要连接到我的应用程序中的远程队列,但是当在 MQ 场中启用安全性时,它会遇到身份验证错误(RC 2035),我被告知,当我使用 spring 配置时,它试图访问一些它不应该访问的默认队列,我遇到了 setDirectAuth 属性,它会解决这个问题吗?如果我错过了导致错误的任何属性,请告知?

错误:

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'connectionFactory' defined in class path resource [META-INF/spring.xml]: Invocation of init method failed; nested exception is javax.naming.ServiceUnavailableException: Unable to connect to the target queue manager XXXX.XXX.XXX.com:1415/xxx.SVRCONN [Root exception is com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2035'.]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'connectionFactory' defined in class path resource [META-INF/spring.xml]: Invocation of init method failed; nested exception is javax.naming.ServiceUnavailableException: Unable to connect to the target queue manager xxxx.xxx.xxx.com:1415/xxx.SVRCONN [Root exception is com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2035'.]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)

上下文.xml

<Resource 
    name="jms/MQConnectionFactory" 
    auth="Container" 
    type="com.ibm.mq.jms.MQQueueConnectionFactory" 
    factory="com.ibm.mq.jms.MQQueueConnectionFactoryFactory" 
    description="JMS Queue Connection Factory for sending messages" 
    HOST="XX.XXX.XXX.XX"
    PORT="XXXX"
    CHAN="MQ.CHANNEL"
    TRAN="1" 
    QMGR="TEST01"
/> 

<Resource 
    name="jms/QueueSU" 
    auth="Container" 
    type="com.ibm.mq.jms.MQQueue" 
    factory="com.ibm.mq.jms.MQQueueFactory" 
    description="JMS Queue for status update" 
    QU="Q01" 
/> 

<Resource 
    name="jms/QueueBM" 
    auth="Container" 
    type="com.ibm.mq.jms.MQQueue" 
    factory="com.ibm.mq.jms.MQQueueFactory" 
    description="JMS Queue for bond management" 
    QU="Q02" 
/> 

属性文件:

#JMS Provider
jms.factory.initial=com.ibm.mq.jms.context.WMQInitialContextFactory
jms.provider.url=xx.xxx.xxx.com:1415/xxx.CHANNEL
destination.factory=java:/comp/env/jms/MQConnectionFactory
bm.queue=java:/comp/env/jms/QueueBM
su.queue=java:/comp/env/jms/QueueSU

春天.xml

   <!--  JMS BEANS  -->   
    <bean id="bmMessageReceiver" class="com.jms.BMMessageReceiver"/> 
    <bean id="suMessageReceiver" class="com.jms.SUMessageReceiver"/>
    <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
        <property name="environment">
            <props>
                <prop key="java.naming.factory.initial">${jms.factory.initial}</prop>
                <prop key="java.naming.provider.url">${jms.provider.url}</prop>
            </props>
        </property>
    </bean>
    <bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate">
            <ref bean="jndiTemplate" />
        </property>
        <property name="jndiName">
            <value>${destination.factory}</value>
        </property>
    </bean>
    <bean id="bmMessageQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate">
            <ref bean="jndiTemplate" />
        </property>
        <property name="jndiName">
            <value>${bm.queue}</value>
        </property>
    </bean>
    <bean id="suMessageQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate">
            <ref bean="jndiTemplate" />
        </property>
        <property name="jndiName">
            <value>${su.queue}</value>
        </property>
    </bean>
    <bean id="bmListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="concurrentConsumers" value="5" />
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="destination" ref="bmMessageQueue" />
        <property name="messageListener" ref="bmMessageReceiver" />
        <property name="sessionTransacted" value="true" />
    </bean>
    <bean id="suListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="concurrentConsumers" value="5" />
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="destination" ref="suMessageQueue" />
        <property name="messageListener" ref="suMessageReceiver" />
        <property name="sessionTransacted" value="true" />
    </bean>    
 <!--    JMS END   --> 
4

1 回答 1

1

当您的应用打开本地队列时,授权配置文件与打开的队列的名称相匹配。换句话说,如果连接到的应用LOCALQMGR打开SYSTEM.DEF.LOCAL.QUEUE@LOCALQMGR授权控制列表条目,则LOCALQMGR必须授予应用访问SYSTEM.DEF.LOCAL.QUEUE.

但是,当应用程序打开SOME.QUEUE@REMOTEQMGRQMgr 时,会解析REMOTEQMGR并找到通向该 QMgr 的传输队列。在这种情况下,它打开的队列是传输队列,因此它会寻找与传输队列匹配的授权配置文件。将应用程序授权给 XMitQ 可以,但它允许应用程序将消息发送到该 QMgr 上的任何队列,包括例如命令队列。

很多时候,管理员不希望直接授予对传输队列的访问权限,因为它允许访问该 QMgr 上的任何队列并且他们宁愿限制它。因此,在点对点界面中,通常会在本地设置一个 QRemote 并授权该应用程序。在集群中,通常在集群队列上设置本地 QAlias 并将授权配置文件附加到该队列。

唯一会影响这一点的是应用程序用于连接请求的用户 ID。如果 QMgr 是安全的,则应用程序无法影响此连接 ID。MQ 管理员将在通道定义中设置 ID 或从 IP 地址或 SSL 证书专有名称映射它。如果由于某种原因 QMgr 不安全,则应用程序可以指定要在连接上使用的 ID 作为 API 调用的一部分:

connection = ConnectionFactory.createConnection(userID, password);

如果 MQ 管理员未MCAUSER在通道上设置或映射,则 QMgr 将接受您提供的 ID,并且不检查密码。如果 MQ 管理员配置了通道出口,该出口可以针对 LDDAP、AD、本地操作系统等验证密码。但如果未安装出口,则不检查密码。

既然您知道了这一点,您也许可以回答有关setDirectAuth(因为我不能)效果的问题。如果该参数由连接工厂继承并由通道请求断言,它将被传递给 MQ,如果通道不安全,则将被接受。类似地,如果您使用了带有 ID 和密码的 Connection 对象构造函数,您可以肯定地声明一个 ID,如果通道不安全,QMgr 将接受该 ID。

您可以使用以下方法对此进行测试:

connection = ConnectionFactory.createConnection('mqm', 'doesntmatter');

如果 QMgr 位于 UNIX/Linux 上且不安全,则应用程序将以mqm. 我不建议这样运行,正确的反应是保护它。但这是一种测试并查看它是否安全的方法。

于 2012-10-10T16:06:57.507 回答