当前位置: 首页 > 知识库问答 >
问题:

未能通过JNDI与Websphere MQ SSL通道连接

葛胜泫
2023-03-14

目前,在WMQ端,有一个名为testmgr的队列管理器。在这个队列管理器下,我创建了两个通道。一个是plain.chl,它没有指定SSL密码规范;另一个是SSL.chl,它用RC4_MD5_US配置SSL密码规范,用可选配置SSL身份验证。

我已经使用IBM密钥管理工具为队列管理器创建了一个密钥存储区。密钥db的路径是[wmq_home]\qmgrs\testmgr\ssl\key

对于通道plain.chl,我定义了一个队列连接工厂,如下所示:

DEF QCF(PlainQCF) QMANAGER(TestMgr) CHANNEL(PLAIN.CHL) HOST(192.168.66.23) PORT(1414)   TRANSPORT(client)
DEF QCF(SSLQCF) QMANAGER(TestMgr) CHANNEL(SSL.CHL) HOST(192.168.66.23) PORT(1414) TRANSPORT(client) SSLCIPHERSUITE(SSL_RSA_WITH_RC4_128_MD5)

现在我只能使用plainqcf创建连接。但未能查找SSL队列连接工厂。我的代码如下所示:

 Hashtable environment = new Hashtable();
    environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.mq.jms.context.WMQInitialContextFactory");
    environment.put(Context.PROVIDER_URL, "192.168.66.23:1414/SSL.CHL");
    Context ctx = new InitialContext( environment );
    QueueConnectionFactory qcf = (QueueConnectionFactory) ctx.lookup("SSLQCF");
    qcf.createConnection();
    ....

在查找SSL工厂时,我是否遗漏了一些上下文属性?连接,然后我发现代码挂在new InitialContext(environment)行上很长时间,几乎5分钟,并且我得到cc=2;rc=2009;amq9208...错误。

如有任何建议,将不胜感激。SSL通道不能通过JNDI连接是真的吗?

@T.Rob,非常感谢你的回复。但是我们仍然希望使用WMQInitialContextFactory,所以恐怕我还需要找到解决方案。

我刚刚定义了连接工厂一次。显示的SSL队列连接工厂信息如下:

InitCtx> DISPLAY QCF(SSLQCF)
ASYNCEXCEPTION(ALL)
CCSID(819)
CHANNEL(SSL.CHL)
CLIENTRECONNECTOPTIONS(ASDEF)
CLIENTRECONNECTTIMEOUT(1800)
COMPHDR(NONE )
COMPMSG(NONE )
CONNECTIONNAMELIST(192.168.66.23(1414))
CONNOPT(STANDARD)
FAILIFQUIESCE(YES)
HOSTNAME(192.168.66.23)
LOCALADDRESS()
MAPNAMESTYLE(STANDARD)
MSGBATCHSZ(10)
MSGRETENTION(YES)
POLLINGINT(5000)
PORT(1414)
PROVIDERVERSION(UNSPECIFIED)
QMANAGER(TestMgr)
RESCANINT(5000)
SENDCHECKCOUNT(0)
SHARECONVALLOWED(YES)
SSLCIPHERSUITE(SSL_RSA_WITH_RC4_128_MD5)
SSLFIPSREQUIRED(NO)
SSLRESETCOUNT(0)
SYNCPOINTALLGETS(NO)
TARGCLIENTMATCHING(YES)
TEMPMODEL(SYSTEM.DEFAULT.MODEL.QUEUE)
TEMPQPREFIX()
TRANSPORT(CLIENT)
USECONNPOOLING(YES)
VERSION(7)
WILDCARDFORMAT(TOPIC_ONLY)

JNDI提供程序应该很好,因为我可以成功地查找普通连接工厂。另外,对于我的客户端应用程序,我从为MQ server创建的密钥存储中提取证书,并将其导入到我的JRE的信任存储(cacerts)中,别名为IBMWebSphereMQTestMgr

您是正确的,2009年错误有一些日志条目:

=================================================================

4/20/2012 20:24:27 - Process(13768.3) User(MUSR_MQADMIN) Program(amqzmur0.exe)
                      Host(xxxx_host of my MQ) Installation(mqenv)
                      VRMF(7.1.0.0) QMgr(TestMgr)                
AMQ6287: WebSphere MQ V7.1.0.0 (p000-L111019).
EXPLANATION:
WebSphere MQ system information: 
Host Info         :- Windows Server 2003, Build 3790: SP2 (MQ Windows 32-bit) 
Installation      :- C:\IBM\WebSphereMQ (mqenv) 
Version           :- 7.1.0.0 (p000-L111019)
ACTION:
None. 

-------------------------------------------------------------------------------
4/20/2012 20:24:27 - Process(7348.116) User(MUSR_MQADMIN) Program(amqrmppa.exe)
                      Host(xxxx_host of my MQ) Installation(mqenv)
                      VRMF(7.1.0.0) QMgr(TestMgr)
AMQ9639: Remote channel 'SSL.CHL' did not specify a CipherSpec.

EXPLANATION:
Remote channel 'SSL.CHL' did not specify a CipherSpec when the local channel
expected one to be specified. 

The remote host is 'xxx_host of my app (192.168.66.25)'. 
The channel did not start.

ACTION:
Change the remote channel 'SSL.CHL' on host 'xxx_host of my app (192.168.66.25)' to
specify a CipherSpec so that both ends of the channel have matching
CipherSpecs.

----- amqcccxa.c : 3817 -------------------------------------------------------
4/20/2012 20:24:27 - Process(7348.116) User(MUSR_MQADMIN) Program(amqrmppa.exe)
                      Host(my app host) Installation(mqenv)
                    VRMF(7.1.0.0) QMgr(TestMgr)                    
AMQ9999: Channel 'SSL.CHL' to host 'xxx_host of my app (192.168.66.25)' ended
abnormally.

====================================================================

我对错误日志也有一些困惑。我的应用程序在一台不同于我的MQ的机器上上演。但是日志显示,更改我的应用程序(192.168.66.25)的主机'XXX_HOST'上的远程通道'SSL.CHL'以指定一个密码规格,以便通道的两端都有匹配的密码规格。如何更改我的应用程序主机上的通道密码规格?

回复评论。

INITIAL_CONTEXT_FACTORY=com.ibm.mq.jms.context.WMQInitialContextFactory
PROVIDER_URL=192.168.66.23:1414/SYSTEM.DEF.SVRCONN

请注意,这里我使用默认通道system.def.svrconn,以便登录到管理控制台。如果将通道更改为SSL OneSSL.chl,我也无法登录到管理控制台。这里发生的错误就像我的客户端应用程序中的错误一样。

另一个说明是,在我的客户端中,我使用以下代码can connect通过通道ssl.chl成功连接qmgr(testmgr)。

   MQConnectionFactory factory = new MQConnectionFactory();
    factory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
    factory.setQueueManager("TestMgr");
    factory.setSSLCipherSuite("SSL_RSA_WITH_RC4_128_MD5");
    factory.setPort(1414);
    factory.setHostName("192.168.66.23");
    factory.setChannel("SSL.CHL");

    MQConnection connection = (MQConnection) factory.createConnection();

现在的问题就像您所说的,即初始上下文通过SSL通道连接到qmgr失败。您提供的选项(Use plain channel for initial context和ssl channel for connection Factory)也有效。但是我仍然想知道如何使用ssl通道工作获得初始上下文。非常感谢你的耐心。您的更新将不胜感激。

共有1个答案

颜功
2023-03-14

我从来都不太喜欢com.ibm.mq.jms.context.wmqInitialContextFactory。它将托管对象存储在队列中。因此,为了查找ConnectionFactory,它告诉JMS如何连接到QMgr,首先需要连接到QMgr进行JNDI调用。因此,在调试SSL连接之前,需要知道底层JNDI提供程序是否正常工作。

如果您希望跳过基于MQ的JNDI提供程序而只使用文件系统,请参阅Bobby Woolf文章的更新版本。如果您想继续使用com.ibm.mq.jms.context.wmqInitialContextFactory,请继续阅读,但要准备提供更多的配置信息。

在运行JMSAdmin工具时,是否在创建对象后显示它们?例如,下面是我的jmsadmin.bat脚本之一:

# Connection Factory for Client mode
# Delete the Connection Factory if it exists
DELETE  CF(JMSDEMOCF)

# Define the Connection Factory
DEFINE  CF(JMSDEMOCF) +
        SYNCPOINTALLGETS(YES) +
        SSLCIPHERSUITE(NULL_SHA) +
        TRAN(client) +
        HOST(127.0.0.1) CHAN(SSL.SVRCONN) PORT(1414) +
        QMGR( )

# Display the resulting definition
DISPLAY CF(JMSDEMOCF)

一旦您知道是应用程序还是JNDI提供程序导致了这个问题(或者切换到另一个不需要MQ连接的JNDI提供程序,例如文件系统的初始上下文),那么就可以确定接下来的步骤。

上面链接的文章提供了使用文件系统JNDI提供程序的代码和托管对象脚本示例。您可能会注意到上面粘贴的脚本使用了相同的QMgr名称。那是因为文章的那部分是我写的。当我想使用相同的示例切换到SSL时,我只需更新ConnectionFactory以指向SSL通道,它就可以工作了。

下面是我修改的示例中的其他部分:

java -Djavax.net.debug=ssl  ^
     -Djavax.net.ssl.trustStore=key2.jks  ^
     -Djavax.net.ssl.keyStore=key2.jks ^
     -Djavax.net.ssl.keyStorePassword=????????  ^
     -Djavax.net.ssl.trustStorePassword=???????? ^
     -cp "%CLASSPATH%"  ^
      com.ibm.examples.JMSDemo -pub -topic JMSDEMOPubTopic %*

Update:
响应这些注释,JMSAdmin工具是WMQ包的一部分。然而,WMQ it附带了用于文件系统上下文和LDAP上下文的JAR。WMQInitialContextFactory是可选的,并作为SupportPac ME01交付。当使用WMQInitialContextFactory和JMSAdmin工具(或JMSAdmin GUI或WMQ Explorer)一起使用时,需要用主机、端口和通道配置PROVIDER_URL。例如:

PROVIDER_URL: <Hostname>:<port>/<SVRCONN Channel Name>
192.168.66.23:1414/SSL.SVRCONN

因此,在再次查看您的文章后,我意识到您确实为WMQInitialContextFactory提供了配置信息。我正在寻找一个jmsadmin.config文件,但它在环境哈希表中。这就是问题所在。您试图将SSL通道用于WMQInitialContextFactory和连接工厂。这就是导致查找失败的原因。WMQInitialContextFactory首先建立一个到QMgre的Java连接,以便在队列中查找获得管理对象,如QCF。为了做到这一点,它需要知道为协商握手而设置信道的密码套件。现在,ciphersuite被记录的唯一位置是在QCF定义中。

尝试添加以下行:

environment.put(MQEnvironment.sslCipherSuite, "SSL_RSA_WITH_RC4_128_MD5");
 类似资料:
  • 问题内容: 您是否知道是否可以通过jndi的数据源像其他任何数据库一样在春季设置mongodb实例? 谢谢 问题答案: 如果您的意思是像具有JDBC访问权限的常规RDBMS,那么答案是否定的。

  • 我使用Weblogic 10.3.3来定义到外部Tibco JMS队列的连接。 我有一个设置: 一个 JMS 模块 添加了外部服务器详细信息,包括 tibco 初始上下文工厂 jndi connection url jndi 属性凭据 set java.nameing.security.principal 在我的代码中,我正在从JNDI执行一个简单的查找。 由于我在weblogic上的配置中有凭据

  • 问题内容: 我正在尝试使用JNDI创建与ActiveMQ的简单连接。 我有 队列名为“ example.A”。 根据接触JNDI的ActiveMQ文档,如果我想通过JNDI使用ConectionFactories和Queues(主题),则必须将jndi.properties文件放在我的类路径中。据我了解,默认情况下,activeMQ类路径是%activemq%/ conf目录。我没有改变。所以我的

  • 我有两台机器:machine foo()运行redis服务器,而machine bar()运行通过Jedis连接到foo的java应用程序。当给jedis提供地址时,一切都很好。 但是我不信任foo和bar之间的路由器,redis也不支持SSL。因此,我设置了一个从bar到foo:的ssh隧道 现在,从bar中,我可以直接在或通过隧道在成功地telnet到foo上的redis。对于jedis,如果

  • RabbitMQ Java客户端有以下概念: -与RabbitMQ服务器实例的连接 -??? 使用者线程池-使用RabbitMQ服务器队列中的消息的线程池 队列-按FIFO顺序保存消息的结构 我试图理解他们之间的关系,更重要的是,他们之间的联系。 我仍然不太清楚是什么,除了这是您发布和使用的结构,并且它是从一个开放的连接创建的。如果有人能向我解释一下“通道”代表什么,可能有助于澄清一些问题。 通道

  • 问题内容: 我已经在两个服务器 A 和 B 之间建立了SSH隧道。 B 有MySQL服务器,这可行: 虽然这不是: 尽管my.cnf具有以下几行: 现在关于隧道。它连接以下内容: 但是当(在 A上 ,端口转发)时,我会 我懂了 当我这样做 我懂了 可能是什么原因?我究竟做错了什么? 问题答案: 这里有三个问题。 1-暂时忘记SSH隧道 您不能将MySQL绑定到多个特定IP。第一个子句被第二个子句覆