业务背景先说明一下
由于业务需要俩个系统之间需要通讯, 走的是webservice 协议, 对方提供得 webservice 接口 https 协议,要求双向认证,一知半解,研究了一下午搞定,在此我把网上的零碎资料,再根据自己理解整理一篇教程.
选择cxf 是和其他的 ws框架做过比较的。cxf 兼容性最好,简单易用,和spring 无缝结合. 如果不会根据对方提供的wsdl 文件生成对应的接口.请看我另一篇博文. http://my.oschina.net/hlevel/blog/281026
什么是https 请先自行搜索了解. 双向认证就得需要我们自己搭建的webservice 也是https 的.接下来就搭建自己的https
准备在那台机器上部署webservice 利用机器上装好的 jdk 在cmd 键入如下
keytool -genkey -alias me -keyalg RSA -keystore me.keystore -validity 3650
然后会让你键入keystore相关信息,密钥得记住 我生成的密钥是123456 ,所有完成后会在cmd当前目录下生成 me.keystore
2 .然后需要把刚才生成me.keystore 导入生成为证书 me.cer
keytool -export -alias me -file me.cer -keystore me.keystore
3. 由于是双向认证所以需要生成一个给其他系统调用的keystore , 这样得到一个me_client.keystore, 这个文件提供给对方系统配置到人家的web 容器,当然自己也可以下载.
keytool -import -alias me -file me.cer -keystore me_client.keystore
4. 配置tomcat 为https 协议, 在tomcat conf/server.xml 第 75行左右 解封注释 配置如下, keystorePass 为刚才证书的密钥,https 默认端口为8443
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="C:\me.keystore"
keystorePass="123456" />
5. 配置config/web.xml 对请求链接拦截, /* 表示拦截所有请求为https 协议, 如下配置添加到web.xml 最底部
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>Client Cert Users-only Area</realm-name>
</login-config>
<security-constraint>
<web-resource-collection >
<web-resource-name >SSL</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
6. 经过以上步骤 自己的https 协议的 webservice 构建起来了,跑起tomcat项目后如下
7 .接下来讲如何调用人家的https webservice , 首先拿到人家https 地址,我就以12306.cn 为代表, 点击图案->证书信息->详 细信息->复制到文件->然后默认下一步下一步导出成功.
8. 得到对方提供的https wsdl 文件地址,导出证书后 cmd 键入如下命令得到keystore
keytool -import -alias 12306 -file 12306.cer -keystore 12306.keystore
9 . 输入的密钥口令,是你自己的密钥,完成后得到 12306.keystore ,然后配置到cxf 配置文件里加入如下代码
我用的是spring 集成环境,
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/configuration/security
http://cxf.apache.org/schemas/configuration/security.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<!--项目自己搭建的webservice-->
<jaxws:endpoint id="eCardTsmWs" implementor="com.test.webservice.service.impl.ECardTsmWsImpl" address="/ECARD_TSM_WS" />
<!--对方提供的webservice 调用-->
<bean id="eCardTsmWsImpl" class="com.test.webservice.service.IECardTsmWs" factory-bean="eCardFactory" factory-method="create"/>
<bean id="eCardFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="com.ishua.coupons.plugins.ecard.webservice.service.IECardTsmWs"/>
<property name="address" value="https://ecardtest.test.com:8443/eCustomer/services/ECARD_TSM_WS?wsdl"/>
</bean>
<http:conduit name="*.http-conduit">
<http:tlsClientParameters disableCNCheck="true">
<!--对方的密钥-->
<sec:trustManagers>
<sec:keyStore type="JKS" password="123456" file="/12306.keystore" />
</sec:trustManagers>
<!--双向认证,自己的密钥
<sec:keyManagers keyPassword="password">
<sec:keyStore type="JKS" password="password" file="/me.keystore"/>
</sec:keyManagers>
-->
<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_NULL_.*</sec:include>
<sec:exclude>.*_DH_anon_.*</sec:exclude>
</sec:cipherSuitesFilter>
</http:tlsClientParameters>
</http:conduit>
总结: 我现在配置的是单项认证, 如果想配置双向的话需要把 server.xml clientAuth="true" 除了自己的keystore之外,还需要放置truststore,truststore是根据对方提供的证书导入的
keytool -genkey 是生成自己的keystore
keytool -export 是从keystore导出证书
keytool -import 是将证书导入到truststore
在项目使用中调用 就是spring 方面的问题了,至此整个环境搭建完毕.