我在使用SSL和与证书进行相互身份验证时创建与Tibco EMS JMS队列的连接(和读取)有一些问题。 这是我的Spring配置:
<!-- TIBCO Connection Factory Bean -->
<bean id="tibcoConnectionFactory" class="com.tibco.tibjms.TibjmsConnectionFactory">
<constructor-arg value="ssl://mytibco.server.address:30113" />
<property name="userName" value="userName" />
<property name="userPassword" value="${tibcoPwd}" />
<property name="connAttemptCount" value="10" />
<property name="connAttemptDelay" value="100" />
<property name="connAttemptTimeout" value="1000" />
<property name="reconnAttemptCount" value="10" />
<property name="reconnAttemptDelay" value="100" />
<property name="reconnAttemptTimeout" value="1000" />
<property name="SSLVendor" value="j2se" />
<property name="SSLEnableVerifyHost" value="false" />
<property name="SSLEnableVerifyHostName" value="false" />
<property name="SSLTrace" value="true" />
<property name="SSLDebugTrace" value="true" />
<property name="SSLIdentity" value="c:\\cert\\testCert.p12" />
<property name="SSLPassword" value="*******" />
</bean>
<!-- Spring CachingConnectionFactory Bean -->
<bean id="tibcoJmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<constructor-arg ref="tibcoConnectionFactory" />
<property name="reconnectOnException" value="true" />
<property name="sessionCacheSize" value="10" />
</bean>
当我尝试在队列中放置一些内容时,我会收到以下堆栈跟踪:
[TIBCO EMS]: [J] [SSL] initializing security with vendor 'j2se'
[TIBCO EMS]: [J] [SSL] client version 5.1.0, security version 3.0.0, SSL initialized with vendor 'j2se'
[TIBCO EMS]: [J] [SSL] WARNING: server verification is disabled, will trust any server.
[TIBCO EMS]: [J] [SSL] reading client identity from byte array, format=AUTO
WARN [jmsContainer-1] org.springframework.jms.listener.DefaultMessageListenerContainer - Execution of JMS message listener failed
org.springframework.jms.JmsSecurityException: Error occured while reading identity data: Invalid or not supported identity data; nested exception is javax.jms.JMSSecurityException: Error occured while reading identity data: Invalid or not supported identity data
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:283)
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:168)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:474)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:436)
...
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:543)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:482)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:451)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:323)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:241)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:982)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:974)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:876)
at java.lang.Thread.run(Thread.java:662)
Caused by: javax.jms.JMSSecurityException: Error occured while reading identity data: Invalid or not supported identity data
at com.tibco.tibjms.TibjmsSSL._identityFromStore(TibjmsSSL.java:2670)
at com.tibco.tibjms.TibjmsSSL.createIdentity(TibjmsSSL.java:2575)
at com.tibco.tibjms.TibjmsxLinkSSL._initSSL(TibjmsxLinkSSL.java:309)
at com.tibco.tibjms.TibjmsxLinkSSL.connect(TibjmsxLinkSSL.java:390)
at com.tibco.tibjms.TibjmsConnection._create(TibjmsConnection.java:1288)
at com.tibco.tibjms.TibjmsConnection.<init>(TibjmsConnection.java:4115)
at com.tibco.tibjms.TibjmsxCFImpl._createImpl(TibjmsxCFImpl.java:209)
at com.tibco.tibjms.TibjmsxCFImpl._createConnection(TibjmsxCFImpl.java:253)
at com.tibco.tibjms.TibjmsConnectionFactory.createConnection(TibjmsConnectionFactory.java:36)
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.access$500(JmsTemplate.java:90)
at org.springframework.jms.core.JmsTemplate$JmsTemplateResourceFactory.createConnection(JmsTemplate.java:1028)
at org.springframework.jms.connection.ConnectionFactoryUtils.doGetTransactionalSession(ConnectionFactoryUtils.java:298)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:458)
... 12 more
到现在为止,我无法成功解决ssl握手问题。 如何解决这个问题?
答案 0 :(得分:2)
您遇到的问题是由于Spring的组合以及com.tibco.tibjms.TibjmsConnectionFactory
重载setSSLIdentity
方法的事实,允许传递byte[]
或String
。
这让令人困惑的Spring正在调用setSSLIdentity(byte[])
,这意味着com.tibco.tibjms.TibjmsConnectionFactory
将字符串c:\\cert\\testCert.p12
的字节视为证书(显然它不是)。
不幸的是,Spring并没有让你强制property
元素上的类型(就像在constructor-arg
上那样,至少在撰写本文时),所以你要使用获取java.utils.Map
并将配置作为属性传递的构造函数:
<bean id="tibcoConnectionFactory" class="com.tibco.tibjms.TibjmsConnectionFactory">
<constructor-arg value="ssl://mytibco.server.address:30113" />
<constructor-arg><null/></constructor-arg>
<constructor-arg>
<util:map>
<entry key="com.tibco.tibjms.factory.username" value="userName"/>
<entry key="com.tibco.tibjms.factory.password" value="${tibcoPwd}"/>
<entry key="com.tibco.tibjms.connect.attemptcount" value="10"/>
<entry key="com.tibco.tibjms.connect.attemptdelay" value="100"/>
<entry key="com.tibco.tibjms.connect.attempttimeout" value="1000"/>
<entry key="com.tibco.tibjms.reconnect.attemptcount" value="10"/>
<entry key="com.tibco.tibjms.reconnect.attemptdelay" value="10-"/>
<entry key="com.tibco.tibjms.reconnect.attempttimeout" value="1000" />
<entry key="com.tibco.tibjms.ssl.vendor" value="j2se"/>
<entry key="com.tibco.tibjms.ssl.enable_verify_host" value="false"/>
<entry key="com.tibco.tibjms.ssl.enable_verify_hostname" value="false"/>
<entry key="com.tibco.tibjms.ssl.trace" value="true"/>
<entry key="com.tibco.tibjms.ssl.debug_trace" value="true"/>
<entry key="com.tibco.tibjms.ssl.identity" value="c:/cert/testCert.p12"/>
<entry key="com.tibco.tibjms.ssl.password" value="value="*******"/>
<util:map>
</constructor-arg>
</bean>
对于寻找其他属性名称的任何人,您可以深入查看关联的 setter 并查看其中的属性名称。
答案 1 :(得分:0)
似乎它没有正确读取.p12。它必须记录如下:
[TIBCO EMS]:[J] [SSL]从文件'c:\ cert \ testCert.p12'中读取客户端身份,格式= PKCS12
请注意格式= ...
答案 2 :(得分:0)
Enter SSLIdentity
as /c:/cert/testCert.p12
. Then only it will recognize your p12 file, else will treat it as byte array
答案 3 :(得分:0)
问题是TibjmsConnectionFactory会重载setSSLIdentity(..)
setter。
可用的制定者是:
setSSLIdentity(byte[] identity)
setSSLIdentity(java.lang.String sslIdentity)
这意味着Spring不知道要调用哪个setter。我还没有研究过这方面的证据,但是从谷歌搜索中我发现由JVM实现来决定将调用哪个setter,在我的例子中,它与每次重启应用程序(Oracle JVM)都不同。实际上这是一个已知问题,请参阅https://github.com/flyway/flyway/issues/890。
一种解决方案是使用包含您的属性的Map
来调用构造函数:
TibjmsConnectionFactory(java.lang.String serverUrl,
java.lang.String clientId,
java.util.Map properties)
PS:很抱歉重新提出一个旧问题,但由于这个问题的流量很大,这可能会对将来有所帮助。