java调用基于https的webservice(不生成密钥,基于spring配置,接收所有证书)

来源:互联网 发布:c语言入门自学代码 编辑:程序博客网 时间:2024/05/19 15:42

我的blog:个人博客

最近工作需要调用外部的webservice,之前一直搞的是基于http的ws,没啥好说的

网上很多教程。这次对方提供的接口是基于https的接口,在网上查找都是需要生成密钥,安全证书

等。各种纠结,生成密钥的方法网上都有介绍,我也了解了下,大致是这样的步骤:

第一步、导出服务器端证书。用ie连接地址,然后出现了证书确认的提示框,点击查看证书-详细信息,点击复制到文件,选择base64编码,导出保存文件为test.cert。
第二步、把证书从其它文件导入到TrustStore文件中。
keytool -import -file test.cer -keystore test_store
第三步、设置java的javax.net.ssl.trustStore的系统属性


System.setProperty(“javax.net.ssl.trustStore”, “D: \\test_store”);//注意是绝对路径 System.setProperty("javax.net.ssl.keyStorePassword", "abc"); 


这样通过应用接口就可以直接访问服务了。

如果基于spring配置的话,cxf官网也给出了例子:

http://cxf.apache.org/docs/client-http-transport-including-ssl-support.html

配置如下:、

<http:conduit name="{http://apache.org/hello_world}HelloWorld.http-conduit">   <http:tlsClientParameters>      <sec:keyManagers keyPassword="password">           <sec:keyStore type="JKS" password="password"                file="my/file/dir/Morpit.jks"/>      </sec:keyManagers>      <sec:trustManagers>          <sec:keyStore type="JKS" password="password"               file="my/file/dir/Truststore.jks"/>      </sec:trustManagers>      <sec:cipherSuitesFilter>        <!-- these filters ensure that a ciphersuite with          export-suitable or null encryption is used,          but exclude anonymous Diffie-Hellman key change as          this is vulnerable to man-in-the-middle attacks -->        <sec:include>.*_EXPORT_.*</sec:include>        <sec:include>.*_EXPORT1024_.*</sec:include>        <sec:include>.*_WITH_DES_.*</sec:include>                <sec:include>.*_WITH_AES_.*</sec:include>        <sec:include>.*_WITH_NULL_.*</sec:include>        <sec:exclude>.*_DH_anon_.*</sec:exclude>      </sec:cipherSuitesFilter>  </http:tlsClientParameters>  <http:authorization>     <sec:UserName>Betty</sec:UserName>     <sec:Password>password</sec:Password>  </http:authorization>      <http:client AutoRedirect="true" Connection="Keep-Alive"/>   </http:conduit>


 

但我们不想搞成这种生成证书的方法 ,网上也有办法实现接收所有证书参考:

http://blog.sina.com.cn/s/blog_557c420e0100pyx7.html

核心的东西就是TrustManager类,自己实现X509TrustManager .

但例子都是基于httpclient的,到底如何配置spring呢,开始纠结了

spring配置webservice的基本例子

<bean id="myServiceSoap" class="com.tmaic.MyServiceSoap "          factory-bean="myServiceFactory" factory-method="create"/>    <bean id="myServiceFactory " class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">        <property name="serviceClass" value="com.tmaic.MyServiceSoap "/>        <property name="address" value="${my.url}"/>        <property name="inInterceptors">            <list>                <ref bean="logIn"/>            </list>        </property>        <property name="outInterceptors">            <list>                <ref bean="logOut"/>            </list>        </property>    </bean>


首先想到的是  将将TrustManger类替换掉成接收所有证书的TrustManager类,

但如何注入是个问题,最后想到拦截器,debug模式进去后果然发现了TrustManger




只需要将这个替换掉就ok,于是写一个interceptor,在spring配置:

<property name="inInterceptors">            <list>                <ref bean="logIn"/>            </list>        </property>        <property name="outInterceptors">            <list>                <ref bean="logOut"/>                <ref bean="myTrust"/>            </list>        </property>

<bean id="myTrust" class="com.tmaic.myTrustInterceptor"/>


myTrustInterceptor主要实现:

public void handleMessage(Message message) throws Fault {          System.out.println("我进来了");        HttpsURLConnectionImpl connection=(HttpsURLConnectionImpl)message.get("http.connection") ;           TrustManager[] myTMs = new TrustManager [] {                          new MyX509TrustManager() };        SSLContext ctx = null;        try{            ctx = SSLContext.getInstance("SSL");            ctx.init(null, myTMs, new java.security.SecureRandom());        } catch (Exception e){ }          connection.setSSLSocketFactory(ctx.getSocketFactory());       connection.setHostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);//        connection.setHostnameVerifier(hv);          System.out.println("我要出去了");    }

这样就可以直接调用服务了。

还有个想法是替换掉JaxWsProxyFactoryBean,实现自己的FactoryBean,这个没能实现,不知道各位看官有没有更好的想法呢?



原创粉丝点击