分享

CXF ws security 案例

 风_宇星 2014-05-09
一、相关概念
提到x509,就不得不提到几个相关概念。
1、Private key
2、Public key
3、KeyStore
4、TrustStore
Private key和Public key很简单,字面意思就可以理解,就是常说的私钥和公钥。
KeyStore和TrustStore简单的说就是存储私钥和密钥的容器。二者从存储结构上面都是一样的,只不过对其概念上做个区分,KeyStore主要用来存储私钥(也可能是Chain),TrustStore是用来存储公钥的。
更详细的可以看另外一篇文章:http://lukejin./blog/605634
在CXF中,使用加密签名的方式作为安全策略,配置上还有些麻烦。
先来看个图:

简单解释一下
1、客户端发送soap到服务端
首先A(客户端)需要使用自己的私钥进行签名,使用B(服务端)的公钥进行加密,然后将soap传给B,B用私钥进行解密,用A的公钥进行验签。
2、服务端返回数据到客户端
首先B用自己的私钥进行签名,用A的公钥进行加密,然后将soap传回给A,A用私钥进行解密,用B的公钥进行验签。
只要搞清楚这个过程,再使用CXF就显得比较容易了。

二、搭建环境

下面我们就可以搭建CXF的环境了
首先用maven创建一个简单的java工程,可以先创建好包com.tongtech.ti.cxf.demo.security
然后上pom文件,将下面的pom文件覆盖你自己工程中的pom文件。
Xml代码  收藏代码
  1. <project xmlns="http://maven./POM/4.0.0" xmlns:xsi="http://www./2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven./POM/4.0.0 http://maven./maven-v4_0_0.xsd">  
  3.     <modelVersion>4.0.0</modelVersion>  
  4.     <groupId>ti-cxf</groupId>  
  5.     <artifactId>ti-cxf-security</artifactId>  
  6.     <version>0.0.1-SNAPSHOT</version>  
  7.     <packaging>jar</packaging>  
  8.     <name>Tongtech Demo for CXF Security with wss4j</name>  
  9.     <properties>  
  10.         <cxf.version>2.4.0-SNAPSHOT</cxf.version>  
  11.     </properties>  
  12.     <dependencies>  
  13.         <dependency>  
  14.             <groupId>org.apache.cxf</groupId>  
  15.             <artifactId>cxf-rt-frontend-jaxws</artifactId>  
  16.             <version>${cxf.version}</version>  
  17.         </dependency>  
  18.         <dependency>  
  19.             <groupId>org.apache.cxf</groupId>  
  20.             <artifactId>cxf-rt-transports-http</artifactId>  
  21.             <version>${cxf.version}</version>  
  22.         </dependency>  
  23.         <dependency>  
  24.             <groupId>org.apache.cxf</groupId>  
  25.             <artifactId>cxf-rt-ws-security</artifactId>  
  26.             <version>${cxf.version}</version>  
  27.         </dependency>  
  28.         <dependency>  
  29.             <groupId>org.apache.cxf</groupId>  
  30.             <artifactId>cxf-rt-transports-http-jetty</artifactId>  
  31.             <version>${cxf.version}</version>  
  32.         </dependency>  
  33.     </dependencies>  
  34.   
  35.     <build>  
  36.         <plugins>  
  37.             <plugin>  
  38.                 <groupId>org.apache.maven.plugins</groupId>  
  39.                 <artifactId>maven-compiler-plugin</artifactId>  
  40.                 <configuration>  
  41.                     <source>1.6</source>  
  42.                     <target>1.6</target>  
  43.                 </configuration>  
  44.             </plugin>  
  45.             <plugin>  
  46.                 <groupId>org.apache.cxf</groupId>  
  47.                 <artifactId>cxf-codegen-plugin</artifactId>  
  48.                 <version>${cxf.version}</version>  
  49.                 <executions>  
  50.                     <execution>  
  51.                         <id>generate-sources-static</id>  
  52.                         <phase>generate-sources</phase>  
  53.                         <configuration>  
  54.                             <sourceRoot>${basedir}/target/generate</sourceRoot>  
  55.                             <wsdlOptions>  
  56.                                 <wsdlOption>  
  57.                                     <wsdl>${basedir}/src/main/java/com/tongtech/ti/cxf/demo/security/security.wsdl</wsdl>  
  58.                                     <extraargs>  
  59.                                         <extraarg>-db</extraarg>  
  60.                                         <extraarg>jaxb</extraarg>  
  61.                                         <extraarg>-p</extraarg>  
  62.                                         <extraarg>com.tongtech.ti.cxf.demo.security.service</extraarg>  
  63.                                         <extraarg>-all</extraarg>  
  64.                                     </extraargs>  
  65.                                 </wsdlOption>  
  66.                             </wsdlOptions>  
  67.                         </configuration>  
  68.                         <goals>  
  69.                             <goal>wsdl2java</goal>  
  70.                         </goals>  
  71.                     </execution>  
  72.                 </executions>  
  73.             </plugin>  
  74.         </plugins>  
  75.     </build>  
  76.   
  77. </project>  


然后在上WSDL:
Security.wsdl
Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <wsdl:definitions name="security"  
  3.     targetNamespace="http://demo.ti./security/" xmlns:wsdl="http://schemas./wsdl/"  
  4.     xmlns:tns="http://demo.ti./security/" xmlns:xsd="http://www./2001/XMLSchema"  
  5.     xmlns:soap="http://schemas./wsdl/soap/">  
  6.     <wsdl:types>  
  7.         <xsd:schema xmlns:xsd="http://www./2001/XMLSchema"  
  8.             targetNamespace="http://demo.ti./security/">  
  9.             <xsd:element name="input">  
  10.                 <xsd:complexType>  
  11.                     <xsd:sequence>  
  12.                         <xsd:element name="in" type="xsd:string"></xsd:element>  
  13.                     </xsd:sequence>  
  14.                 </xsd:complexType>  
  15.             </xsd:element>  
  16.             <xsd:element name="inputResponse">  
  17.                 <xsd:complexType>  
  18.                     <xsd:sequence>  
  19.                         <xsd:element name="out" type="xsd:string"></xsd:element>  
  20.                     </xsd:sequence>  
  21.                 </xsd:complexType>  
  22.             </xsd:element>  
  23.         </xsd:schema>  
  24.     </wsdl:types>  
  25.     <wsdl:message name="inputRequest">  
  26.         <wsdl:part name="parameters" element="tns:input"></wsdl:part>  
  27.     </wsdl:message>  
  28.     <wsdl:message name="inputResponse">  
  29.         <wsdl:part name="parameters" element="tns:inputResponse"></wsdl:part>  
  30.     </wsdl:message>  
  31.     <wsdl:portType name="ISecuriyDemo">  
  32.         <wsdl:operation name="input">  
  33.             <wsdl:input message="tns:inputRequest"></wsdl:input>  
  34.             <wsdl:output message="tns:inputResponse"></wsdl:output>  
  35.         </wsdl:operation>  
  36.     </wsdl:portType>  
  37.     <wsdl:binding name="ISecurityBinding" type="tns:ISecuriyDemo">  
  38.         <soap:binding style="document"  
  39.             transport="http://schemas./soap/http" />  
  40.         <wsdl:operation name="input">  
  41.             <soap:operation soapAction="http://demo.ti./security/input" />  
  42.             <wsdl:input>  
  43.                 <soap:body use="literal" />  
  44.             </wsdl:input>  
  45.             <wsdl:output>  
  46.                 <soap:body use="literal" />  
  47.             </wsdl:output>  
  48.         </wsdl:operation>  
  49.     </wsdl:binding>  
  50.     <wsdl:service name="ISecuriyService">  
  51.         <wsdl:port name="ISecuriyServicePort" binding="tns:ISecurityBinding">  
  52.             <soap:address location="http://localhost:8080/sec" />  
  53.         </wsdl:port>  
  54.     </wsdl:service>  
  55. </wsdl:definitions>  

wsdl文件放在com.tongtech.ti.cxf.demo.security包下面。

下面执行mvn eclipse:myeclipse/eclipse:eclipse/idea:idea,maven会自动根据wsdl创建相关代码。代码生成后拷贝到com.tongtech.ti.cxf.demo.security.service下面。
三、编写代码
(一)生成证书
生成证书还是比较麻烦的,要用到jdk的一个工具——keytool
首先,创建客户端KeyStore和公钥
在命令行运行:
1、创建私钥和KeyStore:
Java代码  收藏代码
  1. keytool -genkey -alias clientprivatekey -keypass keypass -keystore Client_KeyStore.jks -storepass storepass -dname "CN=,C=CN" -keyalg RSA  

创建KeyStore,文件名字为Client_KeyStore.jks,里面有个名为clientprivatekey的私钥。
2、给私钥进行自签名:
Java代码  收藏代码
  1. keytool -selfcert -keystore Client_KeyStore.jks -storepass storepass -alias clientprivatekey -keypass keypass  

签名成功,无任何提示。
3、导出私钥
作用是导出的证书将作为公钥保存到TrustStore中。
Java代码  收藏代码
  1. keytool -export -alias clientprivatekey -file Client_PublicCert.cer -keystore Client_KeyStore.jks -storepass storepass  

如果成功,可以看到提示:
保存在文件中的认证 <Client_PublicCert.cer>
然后创建服务端KeyStore
1、创建私钥和KeyStore
Java代码  收藏代码
  1. keytool -genkey -alias serverprivatekey -keypass keypass -keystore Server_KeyStore.jks -storepass storepass -dname "CN=,C=CN" -keyalg RSA  

2、给私钥进行自签名
Java代码  收藏代码
  1. keytool -selfcert -keystore Server_KeyStore.jks -storepass storepass -alias serverprivatekey -keypass keypass  

3、导出私钥
Java代码  收藏代码
  1. keytool -export -alias serverprivatekey -file Server_PublicCert.cer -keystore Server_KeyStore.jks -storepass storepass  

接下来,将客户端公钥导入到服务端TrustStore中,将服务端公钥导入到客户端TrustStore中。
在命令行中输入:
Java代码  收藏代码
  1. keytool -import -alias clientpublickey -file Client_PublicCert.cer -keystore Server_TrustStore.jks -storepass storepass  

回车后会提示
引用
所有者:CN=, C=CN
签发人:CN=, C=CN
序列号:4cc7e86c
有效期: Wed Oct 27 16:53:00 CST 2010 至Tue Jan 25 16:53:00 CST 2011
证书指纹:
         MD5:FB:AB:71:9F:56:F3:CB:65:16:DC:52:E0:2D:27:FF:F6
         SHA1:06:A8:B1:B4:E2:42:9D:B2:F7:99:E7:70:34:08:96:52:E1:CD:4A:76
         签名算法名称:SHA1withRSA
         版本: 3
信任这个认证? [否]: 

打y即可,然后提示
引用
认证已添加至keystore中

同理,将服务端公钥导入到客户端TrustStore中
Java代码  收藏代码
  1. keytool -import -alias serverpublickey -file Server_PublicCert.cer -keystore Client_TrustStore.jks -storepass storepass  

同样会出现提示,打y回车,提示成功就可以了。
到这里会有个疑问,为什么都叫keystore?在最上面已经提到,KeyStore和TrustStore是概念上的区分。

(二)编写代码
将上面生成好的maven工程导入到eclipse中,在src/main/java下建立新的包,起名叫cert,将刚刚生成好的KeyStore和TrustStore拷到cert包下。
1、创建配置文件
建立客户端加密/解密配置:Client_Encrypt.properties
Java代码  收藏代码
  1. org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin  
  2. org.apache.ws.security.crypto.merlin.keystore.type=jks  
  3. org.apache.ws.security.crypto.merlin.keystore.password=storepass  
  4. org.apache.ws.security.crypto.merlin.keystore.alias=serverpublickey  
  5. org.apache.ws.security.crypto.merlin.file=cert/Client_TrustStore.jks  

建立客户端验签/签名配置:Client_Sign.properties
Java代码  收藏代码
  1. org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin  
  2. org.apache.ws.security.crypto.merlin.keystore.type=jks  
  3. org.apache.ws.security.crypto.merlin.keystore.password=storepass  
  4. org.apache.ws.security.crypto.merlin.keystore.alias=clientprivatekey  
  5. org.apache.ws.security.crypto.merlin.file=cert/Client_KeyStore.jks  

建立服务端加密/解密配置:Server_Decrypt.properties
Java代码  收藏代码
  1. org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin  
  2. org.apache.ws.security.crypto.merlin.keystore.type=jks  
  3. org.apache.ws.security.crypto.merlin.keystore.password=storepass  
  4. org.apache.ws.security.crypto.merlin.keystore.alias=serverprivatekey  
  5. org.apache.ws.security.crypto.merlin.file=cert/Server_KeyStore.jks  

建立服务端验签/签名配置:Server_SignVerf.properties
Java代码  收藏代码
  1. org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin  
  2. org.apache.ws.security.crypto.merlin.keystore.type=jks  
  3. org.apache.ws.security.crypto.merlin.keystore.password=storepass  
  4. org.apache.ws.security.crypto.merlin.keystore.alias=clientpublickey  
  5. org.apache.ws.security.crypto.merlin.file=cert/Server_TrustStore.jks  

整理一下:
引用

可能说这里名字起的有些怪异,这些文件是我从cxf的example中拷贝过来,我想原意应该是客户端进行签名加密,服务器进行验签解密,并没有对返回数据进行签名加密的意图,所以名字起成这样,不过没关系,整理一下,思路会更清楚。
Client_Encrypt.properties————Client_TrustStore.jks————serverpublickey
Client_Sign.properties————Client_KeyStore.jks————clientprivatekey
Server_Decrypt.properties————Server_KeyStore.jks————serverprivatekey
Server_SignVerf.properties————Server_TrustStore.jks————clientpublickey

2、编写客户端、服务端以及各自的Callback
首先先将target/generate中将代码拷贝到com.tongtech.ti.cxf.demo.security.service中,然后在security目录下面建立X509.client和X509.server,分别把ISecuriyDemo_ISecuriyServicePort_Client.java和ISecuriyDemo_ISecuriyServicePort_Server.java改名成Client和Server并移动到X509.client和X509.server包下,然后在client包下建立UTPasswordClientCallBack.java类。
UTPasswordClientCallBack.java代码如下:
Java代码  收藏代码
  1. package com.tongtech.ti.cxf.demo.security.X509.client;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.security.auth.callback.Callback;  
  6. import javax.security.auth.callback.CallbackHandler;  
  7. import javax.security.auth.callback.UnsupportedCallbackException;  
  8.   
  9. import org.apache.ws.security.WSPasswordCallback;  
  10.   
  11. public class UTPasswordClientCallBack implements CallbackHandler {  
  12.   
  13.     public void handle(Callback[] callbacks) throws IOException,  
  14.             UnsupportedCallbackException {  
  15.         WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];  
  16.         pc.setPassword("keypass");  
  17.         System.out.println("Client Identifier=" + pc.getIdentifier());  
  18.         System.out.println("Client Password=" + pc.getPassword());  
  19.     }  
  20.   
  21. }  


在server包下建立UTPasswordServerCallBack.java
UTPasswordServerCallBack.java代码如下:
Java代码  收藏代码
  1. package com.tongtech.ti.cxf.demo.security.X509.server;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.security.auth.callback.Callback;  
  6. import javax.security.auth.callback.CallbackHandler;  
  7. import javax.security.auth.callback.UnsupportedCallbackException;  
  8.   
  9. import org.apache.ws.security.WSPasswordCallback;  
  10.   
  11. public class UTPasswordServerCallBack implements CallbackHandler {  
  12.   
  13.     public void handle(Callback[] callbacks) throws IOException,  
  14.             UnsupportedCallbackException {  
  15.         WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];  
  16.         pc.setPassword("keypass");  
  17.         System.out.println("Server Identifier=" + pc.getIdentifier());  
  18.         System.out.println("Server Password=" + pc.getPassword());  
  19.     }  
  20. }  

这两个类中,pc.setPassword方法参数都是keypass,因为我们生成的所有密钥的密码均是keypass,如果密钥密码不同,在这里需要对密钥的Identifier(等同于alias)进行判断,从而设置不同的密码。

接下来将要编写客户端和服务端了。
首先打开Client.java类,将如下代码完整复制,覆盖进去
Java代码  收藏代码
  1. package com.tongtech.ti.cxf.demo.security.X509.client;  
  2.   
  3. /** 
  4.  * Please modify this class to meet your needs 
  5.  * This class is not complete 
  6.  */  
  7.   
  8. import java.net.URL;  
  9. import java.util.HashMap;  
  10. import java.util.Map;  
  11.   
  12. import javax.xml.namespace.QName;  
  13.   
  14. import org.apache.cxf.endpoint.Endpoint;  
  15. import org.apache.cxf.frontend.ClientProxy;  
  16. import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;  
  17. import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;  
  18. import org.apache.ws.security.handler.WSHandlerConstants;  
  19.   
  20. import com.tongtech.ti.cxf.demo.security.service.ISecuriyDemo;  
  21. import com.tongtech.ti.cxf.demo.security.service.ISecuriyService;  
  22.   
  23. /** 
  24.  * This class was generated by Apache CXF 2.4.0-SNAPSHOT Tue Oct 26 16:45:43 CST 
  25.  * 2010 Generated source version: 2.4.0-SNAPSHOT 
  26.  *  
  27.  */  
  28.   
  29. public final class Client {  
  30.   
  31.     private static final QName SERVICE_NAME = new QName(  
  32.             "http://demo.ti./security/", "ISecuriyService");  
  33.   
  34.     private Client() {  
  35.     }  
  36.   
  37.     public static void main(String args[]) throws Exception {  
  38.         URL wsdlURL = ISecuriyService.WSDL_LOCATION;  
  39.   
  40.         ISecuriyService ss = new ISecuriyService(wsdlURL, SERVICE_NAME);  
  41.         ISecuriyDemo port = ss.getISecuriyServicePort();  
  42.         org.apache.cxf.endpoint.Client client = ClientProxy.getClient(port);  
  43.         Endpoint cxfEp = client.getEndpoint();  
  44.   
  45.         // Clint Out  
  46.         Map<String, Object> outProp = new HashMap<String, Object>();  
  47.         outProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP  
  48.                 + " " + WSHandlerConstants.SIGNATURE + " "  
  49.                 + WSHandlerConstants.ENCRYPT);  
  50.         outProp.put(WSHandlerConstants.USER, "clientprivatekey");  
  51.         outProp.put(WSHandlerConstants.ENCRYPTION_USER, "serverpublickey");  
  52.         outProp.put(WSHandlerConstants.PW_CALLBACK_CLASS,  
  53.                 UTPasswordClientCallBack.class.getName());  
  54.         outProp.put(WSHandlerConstants.SIG_PROP_FILE,  
  55.                 "cert/Client_Sign.properties");  
  56.         outProp.put(WSHandlerConstants.ENC_PROP_FILE,  
  57.                 "cert/Client_Encrypt.properties");  
  58.         cxfEp.getOutInterceptors().add(new WSS4JOutInterceptor(outProp));  
  59.   
  60.         // Client In(Return)  
  61.         Map<String, Object> inProp = new HashMap<String, Object>();  
  62.         inProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP  
  63.                 + " " + WSHandlerConstants.SIGNATURE + " "  
  64.                 + WSHandlerConstants.ENCRYPT);  
  65.         inProp.put(WSHandlerConstants.PW_CALLBACK_CLASS,  
  66.                 UTPasswordClientCallBack.class.getName());  
  67.         inProp.put(WSHandlerConstants.DEC_PROP_FILE,  
  68.                 "cert/Client_Sign.properties");  
  69.         inProp.put(WSHandlerConstants.SIG_PROP_FILE,  
  70.                 "cert/Client_Encrypt.properties");  
  71.         cxfEp.getInInterceptors().add(new WSS4JInInterceptor(inProp));  
  72.   
  73.         {  
  74.             System.out.println("Invoking input...");  
  75.             java.lang.String _input_in = "Input Value!";  
  76.             java.lang.String _input__return = port.input(_input_in);  
  77.             System.out.println("input.result=" + _input__return);  
  78.         }  
  79.   
  80.         System.exit(0);  
  81.     }  
  82.   
  83. }  


打开Server.java,同理将下面代码完整复制并完整覆盖:
Java代码  收藏代码
  1. package com.tongtech.ti.cxf.demo.security.X509.server;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. import javax.xml.ws.Endpoint;  
  7.   
  8. import org.apache.cxf.jaxws.EndpointImpl;  
  9. import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;  
  10. import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;  
  11. import org.apache.ws.security.handler.WSHandlerConstants;  
  12.   
  13. import com.tongtech.ti.cxf.demo.security.service.ISecuriyDemoImpl;  
  14.   
  15. /** 
  16.  * This class was generated by Apache CXF 2.4.0-SNAPSHOT Tue Oct 26 16:45:43 CST 
  17.  * 2010 Generated source version: 2.4.0-SNAPSHOT 
  18.  *  
  19.  */  
  20.   
  21. public class Server {  
  22.   
  23.     protected Server() throws Exception {  
  24.         System.out.println("Starting Server");  
  25.         Object implementor = new ISecuriyDemoImpl();  
  26.         String address = "http://localhost:8080/sec";  
  27.         EndpointImpl ep = (EndpointImpl) Endpoint.publish(address, implementor);  
  28.         org.apache.cxf.endpoint.Endpoint cxfEp = ep.getServer().getEndpoint();  
  29.   
  30.         // ///////////////////////////////////////////////////////////////  
  31.   
  32.         Map<String, Object> inProp = new HashMap<String, Object>();  
  33.         inProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP  
  34.                 + " " + WSHandlerConstants.SIGNATURE + " "  
  35.                 + WSHandlerConstants.ENCRYPT);  
  36.         inProp.put(WSHandlerConstants.PW_CALLBACK_CLASS,  
  37.                 UTPasswordServerCallBack.class.getName());  
  38.         inProp.put(WSHandlerConstants.SIG_PROP_FILE,  
  39.                 "cert/Server_SignVerf.properties");  
  40.         inProp.put(WSHandlerConstants.DEC_PROP_FILE,  
  41.                 "cert/Server_Decrypt.properties");  
  42.         cxfEp.getInInterceptors().add(new WSS4JInInterceptor(inProp));  
  43.   
  44.         // /////////////////////////////////////////////////////////////////  
  45.   
  46.         Map<String, Object> outProp = new HashMap<String, Object>();  
  47.         outProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP  
  48.                 + " " + WSHandlerConstants.SIGNATURE + " "  
  49.                 + WSHandlerConstants.ENCRYPT);  
  50.         outProp.put(WSHandlerConstants.USER, "serverprivatekey");  
  51.         outProp.put(WSHandlerConstants.PW_CALLBACK_CLASS,  
  52.                 UTPasswordServerCallBack.class.getName());  
  53.         outProp.put(WSHandlerConstants.ENCRYPTION_USER, "clientpublickey");  
  54.         outProp.put(WSHandlerConstants.SIG_PROP_FILE,  
  55.                 "cert/Server_Decrypt.properties");// 私钥  
  56.         outProp.put(WSHandlerConstants.ENC_PROP_FILE,  
  57.                 "cert/Server_SignVerf.properties");// 公钥  
  58.         cxfEp.getOutInterceptors().add(new WSS4JOutInterceptor(outProp));  
  59.     }  
  60.   
  61.     public static void main(String args[]) throws Exception {  
  62.         new Server();  
  63.         System.out.println("Server ready...");  
  64.   
  65.         Thread.sleep(60 * 60 * 1000);  
  66.         System.out.println("Server exiting");  
  67.         System.exit(0);  
  68.     }  
  69. }  


复制完成后,运行服务端和客户端进行测试即可。没有出以外的话,客户端能够顺利收到返回信息。

如果要看soap内容,打开service包下的ISecuriyDemo.java,加入如下标注代码:
Java代码  收藏代码
  1. @WebService(targetNamespace = "http://demo.ti./security/", name = "ISecuriyDemo")  
  2. @XmlSeeAlso({ObjectFactory.class})  
  3. //====加入如下代码====  
  4. @InInterceptors(interceptors = { "org.apache.cxf.interceptor.LoggingInInterceptor" })  
  5. @OutInterceptors(interceptors = { "org.apache.cxf.interceptor.LoggingOutInterceptor" })  
  6. //====加入代码结束====  
  7. public interface ISecuriyDemo {  
  8.   
  9.     @WebResult(name = "out", targetNamespace = "")  
  10.     @RequestWrapper(localName = "input", targetNamespace = "http://demo.ti./security/", className = "com.tongtech.ti.cxf.demo.security.service.Input")  
  11.     @WebMethod(action = "http://demo.ti./security/input")  
  12.     @ResponseWrapper(localName = "inputResponse", targetNamespace = "http://demo.ti./security/", className = "com.tongtech.ti.cxf.demo.security.service.InputResponse")  
  13.     public java.lang.String input(  
  14.         @WebParam(name = "in", targetNamespace = "")  
  15.         java.lang.String in  
  16.     );  
  17. }  


最后以客户端为例,简单讲解一下出入站配置:
客户端包括:
Java代码  收藏代码
  1. org.apache.cxf.endpoint.Client client = ClientProxy.getClient(port);  
  2. Endpoint cxfEp = client.getEndpoint();  
  3.   
  4. // Clint Out  
  5. Map<String, Object> outProp = new HashMap<String, Object>();  
  6. outProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP  
  7.         + " " + WSHandlerConstants.SIGNATURE + " "  
  8.         + WSHandlerConstants.ENCRYPT);  
  9. outProp.put(WSHandlerConstants.USER, "clientprivatekey");  
  10. outProp.put(WSHandlerConstants.ENCRYPTION_USER, "serverpublickey");  
  11. outProp.put(WSHandlerConstants.PW_CALLBACK_CLASS,  
  12.         UTPasswordClientCallBack.class.getName());  
  13. outProp.put(WSHandlerConstants.SIG_PROP_FILE,  
  14.         "cert/Client_Sign.properties");  
  15. outProp.put(WSHandlerConstants.ENC_PROP_FILE,  
  16.         "cert/Client_Encrypt.properties");  
  17. cxfEp.getOutInterceptors().add(new WSS4JOutInterceptor(outProp));  
  18.   
  19. // Client In(Return)  
  20. Map<String, Object> inProp = new HashMap<String, Object>();  
  21. inProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP  
  22.         + " " + WSHandlerConstants.SIGNATURE + " "  
  23.         + WSHandlerConstants.ENCRYPT);  
  24. inProp.put(WSHandlerConstants.PW_CALLBACK_CLASS,  
  25.         UTPasswordClientCallBack.class.getName());  
  26. inProp.put(WSHandlerConstants.DEC_PROP_FILE,  
  27.         "cert/Client_Sign.properties");  
  28. inProp.put(WSHandlerConstants.SIG_PROP_FILE,  
  29.         "cert/Client_Encrypt.properties");  
  30. cxfEp.getInInterceptors().add(new WSS4JInInterceptor(inProp));  

第一行,使用CXF的Client代理(ClientProxy)来获得Endpoint,然后将WSS4J的Intercepter加入到Endpoint中。
需要加入两个WSS4J的Intercepter,WSS4JOutInterceptor和WSS4JInInterceptor,outIntercepter是客户端向服务端请求时,作为客户端出站(OutBound)的Intercepter,需要配置WSS4J相关属性:
WSHandlerConstants.ACTION,WSHandlerConstants.USER,WSHandlerConstants.ENCRYPTION_USER,WSHandlerConstants.PW_CALLBACK_CLASS,WSHandlerConstants.SIG_PROP_FILE,WSHandlerConstants.ENC_PROP_FILE,将这些属性放入map中,传入WSS4JOutInterceptor中。
对于客户端出站来说,签名需要客户端私钥(Client_Sign.properties)进行签名,加密需要服务端公钥(Client_Encrypt.properties)进行加密,属性中WSHandlerConstants.SIG_PROP_FILE为签名配置文件,WSHandlerConstants.ENC_PROP_FILE为加密配置文件。
入站则相反,验签需要服务端公钥(Client_Encrypt.properties),解密需要客户端私钥(Client_Sign.properties)。
服务器端与客户端相反,意思和客户端相同。  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多