java Spring JmsTemplate + 安全

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3196966/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 00:46:13  来源:igfitidea点击:

Spring JmsTemplate + Security

javasecurityspringjmsjmstemplate

提问by James

I've just refactored some code that published to a JMS topic to use Spring's JmsTemplate class and now I'm receiving an exception stating I'm not authenticated.

我刚刚重构了一些发布到 JMS 主题的代码以使用 Spring 的 JmsTemplate 类,现在我收到一个异常,说明我没有通过身份验证。

Previously I created the factory, made a connection, then session etc as follows:

以前我创建了工厂,建立了连接,然后会话等如下:

MQTopicConnectionFactory factory = new MQTopicConnectionFactory();
factory.setQueueManager(qMgr);   
factory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
factory.setHostName(hostname);
factory.setPort(listenerPort);
factory.setChannel(channel);
// setting username and password to be empty string ==> no authentication
connection = factory.createConnection("", "");   
...
connection.start();

I don't see anywhere in the JmsTemplate to set the username and password to empty strings. My config looks like this:

我在 JmsTemplate 中没有看到将用户名和密码设置为空字符串的任何地方。我的配置是这样的:

<bean id="jmsFactory" class="com.ibm.mq.jms.MQTopicConnectionFactory">
    <property name="queueManager">
        <value>ACT01</value>
    </property>
    <property name="hostName">
        <value>xx.xx.xx.xx</value>
    </property>
    <property name="port">
        <value>15004</value>
    </property>
    <property name="transportType">
        <value>1</value>
    </property>
    <property name="channel">
        <value>CONDUCTOR.ACT01</value>
    </property>
</bean>

<bean id="impactJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory">
        <bean class="org.springframework.jms.connection.SingleConnectionFactory">
            <property name="targetConnectionFactory">
                <ref local="jmsFactory" />
            </property>
        </bean>
    </property>
</bean>

I have also tried wrapping the jmsFactory in a UserCredentialsConnectionFactoryAdapterobject to no avail:

我也试过将 jmsFactory 包装在一个UserCredentialsConnectionFactoryAdapter对象中但无济于事:

<bean id="jmsConnectionFactory" class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
    <property name="targetConnectionFactory" ref="jmsFactory"/>
    <property name="username" value=""/>
    <property name="password" value=""/>
</bean> 

Stack trace:

堆栈跟踪:

Caused by: com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager 'LOROL' with connection mode 'Client' and host name 'xx.xx.xx.xx'. Please check if the supplied username and password are correct on the QueueManager you are connecting to
at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:531)
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:219)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:410)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:7855)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:7331)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:276)
at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6055)
at com.ibm.mq.jms.MQTopicConnectionFactory.createTopicConnection(MQTopicConnectionFactory.java:114)
at com.ibm.mq.jms.MQTopicConnectionFactory.createConnection(MQTopicConnectionFactory.java:197)
at org.springframework.jms.connection.SingleConnectionFactory.doCreateConnection(SingleConnectionFactory.java:343)
at org.springframework.jms.connection.SingleConnectionFactory.initConnection(SingleConnectionFactory.java:290)
at org.springframework.jms.connection.SingleConnectionFactory.createConnection(SingleConnectionFactory.java:227)
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:184)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:461)
... 25 more
Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:206)
... 37 more

采纳答案by T.Rob

A few options here...

这里有几个选项......

  • The properties you were setting before resulted in the channel running as an administrator. To get the same functionality you can set the channel's MCAUSER to whatever ID the QMgr is running as (commonly mqm for UNIX and MUSR_MQADMIN on Windows). Boom. Done. Bob's yer uncle.
  • Yes, this does mean that anyone connecting to that channel is an administrator. On the other hand, this is no worse than it was before as demonstrated by your previous code working the way it did.
  • You can still use Spring and pass in the ID and password as described in this forum post. Just keep in mind the password is not actually checked. Whatever ID you pass in is accepted at face value unless you use a channel exit to validate it.
  • 您之前设置的属性导致通道以管理员身份运行。要获得相同的功能,您可以将通道的 MCAUSER 设置为 QMgr 正在运行的任何 ID(通常为 UNIX 的 mqm 和 Windows 上的 MUSR_MQADMIN)。繁荣。完毕。鲍勃的叔叔。
  • 是的,这确实意味着连接到该频道的任何人都是管理员。另一方面,这并不比以前更糟,正如您之前的代码以它的方式工作所证明的那样。
  • 您仍然可以使用 Spring 并按照本论坛帖子中的描述传递 ID 和密码。请记住,实际上并未检查密码。除非您使用通道出口来验证它,否则您传入的任何 ID 都会按面值接受。

For more on WMQ security over client connections, see the Hardening WebSphere MQ presentation. If you wanted to actually secure access to the QMgr you'd want to set MCAUSER to a low-privileged user ID, perform setmqaut commands to authorize that ID's group and then lock down all the other channels like SYSTEM.AUTO.* and SYSTEM.DEF.* so they could not run.

有关客户端连接上的 WMQ 安全性的更多信息,请参阅强化 WebSphere MQ 演示。如果您想真正保护对 QMgr 的访问,您需要将 MCAUSER 设置为低特权用户 ID,执行 setmqaut 命令来授权该 ID 的组,然后锁定所有其他通道,如 SYSTEM.AUTO.* 和 SYSTEM。 DEF.* 所以他们无法运行。

回答by Sherin Syriac

I am running Websphere in my local windows machine and connecting to MQ server in Unix machine . For me only the third option worked. Setting the userID from console didn't work.I tried both mqm and MUSR_MQADMIN.

我在本地 Windows 机器上运行 Websphere 并在 Unix 机器上连接到 MQ 服务器。对我来说,只有第三个选项有效。从控制台设置用户 ID 不起作用。我尝试了 mqm 和 MUSR_MQADMIN。

//connection created using username and password QueueConnection connection = factory.createQueueConnection("mqm","mqm");

//使用用户名和密码创建的连接 QueueConnection connection = factory.createQueueConnection("mqm","mqm");