带有 https 和未签名证书的 Spring HTTP 调用程序
我们已经使用 Springs HttpInvoker 几个星期了,它的工作方式非常神奇。从我的前端(Web)应用程序,我连接到后端的 userService,如下所示:
<bean id="userService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl" value="http://${backend.host}/backend-ws/remoting/UserService"/>
<property name="serviceInterface" value="com...service.UserService"/>
</bean>
然后将 UserService 很好地注入到我们的前端类中。
现在我们将其部署在适当的 (WAS7) 服务器上,并且要求使用 SSL (https)。因此,我将 http(serviceUrl)更改为 https,但随后我得到:
org.springframework.remoting.RemoteAccessException: Could not access HTTP invoker remote service at [https://pbp-dev.dev.echonet/public/backend-ws/remoting/ParameterHelper]; nested exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
这是有道理的,因为安装在服务器(WAS 运行的位置)上的证书未由 CA 签名。
我们已经有一些这方面的经验,因为在同一个 WAS 上运行着一个 Web 服务;为此,我们使用 cxf 并生成了一个 jks 文件(使用 keytool),该文件驻留在客户端应用程序中,并设置如下:
<http:conduit name="https://serverurl/.*">
<http:tlsClientParameters secureSocketProtocol="SSL" disableCNCheck="false">
<sec:trustManagers>
<sec:keyStore type="jks" password="pass123" resource="trust.jks"/>
</sec:trustManagers>
</http:tlsClientParameters>
我想对于 Http Invoker,我们需要做类似的事情,但我们不知道如何在调用程序中使用这个 trust.jks。
我发现的一件事是使用不同的 requestExecutor;像这样:
<bean id="userService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl" value="https://${backend.host}/backend-ws/remoting/UserService"/>
<property name="serviceInterface" value="com...service.UserService"/>
<property name="httpInvokerRequestExecutor">
<bean class="org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor" />
</property>
</bean>
此后我不再收到证书错误,但 userService 似乎没有被创建,从那以后我得到:
NoSuchBeanDefinitionException: No matching bean of type [com...service.UserService] found for dependency
We've been using Springs HttpInvoker for a few weeks now and it works like a charm. From my front end (web)application I connect to the backend's userService like this:
<bean id="userService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl" value="http://${backend.host}/backend-ws/remoting/UserService"/>
<property name="serviceInterface" value="com...service.UserService"/>
</bean>
The UserService is then nicely injected into our front end classes.
Now we're deploying this on a proper (WAS7) server and the requirement there is to use SSL (https). So, I change the http (of the serviceUrl) to https but then I get:
org.springframework.remoting.RemoteAccessException: Could not access HTTP invoker remote service at [https://pbp-dev.dev.echonet/public/backend-ws/remoting/ParameterHelper]; nested exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
which makes sense because the certificate installed on the server (where WAS runs) is not signed by a CA.
We already have some experience with this since on the same WAS there is a webservice running; for this we use cxf and we have generated a jks file (with keytool) that resides in the client application and is set as following:
<http:conduit name="https://serverurl/.*">
<http:tlsClientParameters secureSocketProtocol="SSL" disableCNCheck="false">
<sec:trustManagers>
<sec:keyStore type="jks" password="pass123" resource="trust.jks"/>
</sec:trustManagers>
</http:tlsClientParameters>
I guess for the Http Invoker we need to do something similar but we have no idea how to use this trust.jks in the invoker.
One thing I did find is to use a different requestExecutor; like this:
<bean id="userService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl" value="https://${backend.host}/backend-ws/remoting/UserService"/>
<property name="serviceInterface" value="com...service.UserService"/>
<property name="httpInvokerRequestExecutor">
<bean class="org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor" />
</property>
</bean>
After this I no longer get the certificate error but the userService does not appear to be created since then I get:
NoSuchBeanDefinitionException: No matching bean of type [com...service.UserService] found for dependency
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以尝试如下操作:
首先编写 org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor 的自定义类:
并在您的 xml 文件中引用该类,而不是
org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor
作为You can try something as follows:
First write a custom class of
org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor
:and refer this class in your xml file instead of
org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor
as如果您混合在这里找到的内容(http://stackoverflow.com/questions/5947162/https-and-self-signed-certificate-issue)来配置返回的 HttpClient 以具有预先配置的 SSLSocketFactory,您可以更改主机名套接字工厂的验证程序接受证书,与此接近:
根据您的配置,除了使用 CommonsHttpInvokerRequestExecutor 之外,您还必须配置使用的 HTTPClient 和 SSL套接字工厂
我知道这可能不能完全回答您的问题,但它是其他搜索的起点!祝你好运,不要忘记发布最终解决方案。
If you mix what you can find here (http://stackoverflow.com/questions/5947162/https-and-self-signed-certificate-issue) to configure the HttpClient returned to have a pre configured SSLSocketFactory, you can change the hostname verifier of the socket factory to accept the cerificate, something close to this:
According to you config, besides using CommonsHttpInvokerRequestExecutor you also have to configure the HTTPClient used and the SSL Socket factory
I know this probably does not completely answer your question but it's a starting point for other searches! Good Luck and don't forget to post the final solution.