`

用axis发布webservices带加密

阅读更多
用axis发布webservices(六)
2007-01-17 08:54 P.M.
签名、加密、解密、身份验证的实现

对SOAP消息的签名、加密、解密、身份验证都放在一个名为WSSHelper的类中进行。


例程7 签名、加密、解密、身份验证功能的实现――WSSHelper.java

package com.hellking.study.webservice;
import com.verisign.messaging.WSSecurity;
...
public class WSSHelper {
    static String PROVIDER="ISNetworks";//JSSE安全提供者。   
   //添加JSSE安全提供者,你也可以使用其它安全提供者。只要支持DESede算法。
    static
    {
    java.security.Security.addProvider(new com.isnetworks.provider.jce.ISNetworksProvider());
    }
    /**
     *对XML文档进行数字签名。
     */
    public static void sign(Document doc, String keystore, String storetype,
                        String storepass, String alias, String keypass) throws Exception {
        FileInputStream fileInputStream = new FileInputStream(keystore);
        java.security.KeyStore keyStore = java.security.KeyStore.getInstance(storetype);
        keyStore.load(fileInputStream, storepass.toCharArray());
        PrivateKey key = (PrivateKey)keyStore.getKey(alias, keypass.toCharArray());
        X509Certificate cert = (X509Certificate)keyStore.getCertificate(alias);

        SigningKey sk = SigningKeyFactory.makeSigningKey(key);
        KeyInfo ki = new KeyInfo();
        ki.setCertificate(cert);

        WSSecurity wSSecurity = new WSSecurity();
        wSSecurity.sign(doc, sk, ki);//签名。
    }
    /**
     *对XML文档进行身份验证。
     */
    public static boolean verify(Document doc, String keystore, String storetype,
                        String storepass) throws Exception {
        FileInputStream fileInputStream = new FileInputStream(keystore);
        java.security.KeyStore keyStore = java.security.KeyStore.getInstance(storetype);
        keyStore.load(fileInputStream, storepass.toCharArray());

        TrustVerifier verifier = new X509TrustVerifier(keyStore);

        WSSecurity wSSecurity = new WSSecurity();
        MessageValidity[] resa = wSSecurity.verify(doc, verifier, null,null);
        if (resa.length > 0)
            return resa[0].isValid();
        return false;
    }
   /**
    *对XML文档进行加密。必须有JSSE提供者才能加密。
    */
    public static void encrypt(Document doc, String keystore, String storetype,
                        String storepass, String alias) throws Exception {
        try
        {
               
        FileInputStream fileInputStream = new FileInputStream(keystore);
        java.security.KeyStore keyStore = java.security.KeyStore.getInstance(storetype);
        keyStore.load(fileInputStream, storepass.toCharArray());
        X509Certificate cert = (X509Certificate)keyStore.getCertificate(alias);
       
        PublicKey pubk = cert.getPublicKey();
        KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede",PROVIDER);       
        keyGenerator.init(168, new SecureRandom());
        SecretKey key = keyGenerator.generateKey();
        KeyInfo ki = new KeyInfo();
        ki.setCertificate(cert);

        WSSecurity wSSecurity = new WSSecurity();
        //加密。
        wSSecurity.encrypt(doc, key, AlgorithmType.TRIPLEDES, pubk, AlgorithmType.RSA1_5, ki);
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    }
    /**
     *对文档进行解密。
     */
    public static void decrypt(Document doc, String keystore, String storetype,
                        String storepass, String alias, String keypass) throws Exception {
        FileInputStream fileInputStream = new FileInputStream(keystore);
        java.security.KeyStore keyStore = java.security.KeyStore.getInstance(storetype);
        keyStore.load(fileInputStream, storepass.toCharArray());
        PrivateKey prvk2 = (PrivateKey)keyStore.getKey(alias, keypass.toCharArray());

        WSSecurity wSSecurity = new WSSecurity();
        //解密。
        wSSecurity.decrypt(doc, prvk2, null);
        WsUtils.removeEncryptedKey(doc);//从 WS-Security Header中删除 EncryptedKey 元素
    }

    public static void removeWSSElements(Document doc) throws Exception {
        WsUtils.removeWSSElements(doc);// 删除WSS相关的元素。
    }       
}



WSSHelper类中使用了ISNetworks安全提供者,ISNetworks实现了RSA加密、解密算法。当然,你也可以使用其它的安全提供者,并且可以使用不同的加密算法。可以从网络上下载ISNetworks相关包。

WSSHelper中包含了一个WsUtils类,它的功能就是从加密后的SOAP消息中删除一些WS-Security元素,删除这些元素后的SOAP消息才能被最终的客户端或者Web服务端处理。

服务器端Handler开发

当请求到达后,服务端Handler调用handleRequest方法,执行如下过程:对请求SOAP消息解密'身份验证'删除WSS元素'把Document转换成SOAP消息。 Web服务端点对请求做出响应后,将调用handleResponse方法,执行如下过程:对响应的SOAP消息进行数字签名'加密'把Document转换成SOAP消息。


例程8 服务器端Handler(WSSecurityServerHandler.java)

package com.hellking.study.webservice;
...

//服务器端Handler
public class WSSecurityServerHandler implements Handler
{
         //密匙库相关信息
private String keyStoreFile = null;
        private String keyStoreType = "JKS";
        。。。
       
        public WSSecurityServerHandler()
        {
            System.out.println("服务端Handler:构造方法");
        }
        /**
         *处理请求
         *流程:解密-->身份验证-->删除WSS元素'把Document转换成SOAP消息。
         */        
        public boolean handleRequest(MessageContext messageContext) {
        
                System.out.println("开始处理请求。。。");
        if (messageContext instanceof SOAPMessageContext){
            try {
    SOAPMessageContext soapMessageContext = (SOAPMessageContext)messageContext;
                SOAPMessage soapMessage = soapMessageContext.getMessage();
                soapMessage.writeTo(System.out);
    Document doc = MessageConveter.convertSoapMessageToDocument(soapMessage);
                    //解密
                WSSHelper.decrypt(doc, keyStoreFile, keyStoreType,
                        keyStorePassword, keyAlias, keyEntryPassword);
                     //身份验证
                WSSHelper.verify(doc, trustStoreFile, trustStoreType, trustStorePassword);
                //删除WSS元素
WSSHelper.removeWSSElements(doc);

                soapMessage = MessageConveter.convertDocumentToSOAPMessage(doc);
                soapMessageContext.setMessage(soapMessage);
            } catch (Exception e){

                System.err.println("在处理请求时发生了异常: " + e);
                e.printStackTrace();
                return false;
            }
        } else {
            System.out.println("MessageContext是以下类的实例: " + messageContext.getClass());
        }
         System.out.println("处理请求完毕!");
        return true;
    }
   
    /**
     *处理响应
     *流程:数字签名-->加密-->把Document转换成SOAP消息。
     */
     public boolean handleResponse(MessageContext messageContext) {
            System.out.println("开始处理Web服务响应。。。");
        if (messageContext instanceof SOAPMessageContext){
            try {
        SOAPMessageContext soapMessageContext = (SOAPMessageContext)messageContext;
                SOAPMessage soapMessage = soapMessageContext.getMessage();
        Document doc = MessageConveter.convertSoapMessageToDocument(soapMessage);
                WSSHelper.sign(doc, keyStoreFile, keyStoreType,
                        keyStorePassword, keyAlias, keyEntryPassword);
                WSSHelper.encrypt(doc, trustStoreFile, trustStoreType,
                        trustStorePassword, certAlias);

                soapMessage = MessageConveter.convertDocumentToSOAPMessage(doc);
                soapMessageContext.setMessage(soapMessage);
            } catch (Exception e){
                System.err.println("在处理响应时发生以下错误: " + e);
                e.printStackTrace();
                return false;
            }
        }
   
        System.out.println("处理响应完毕!");
        return true;
    }
    /**
     *初始化,主要是初始化一些相关参数。
     */
     public void init(HandlerInfo config) {
        System.out.println("WSSecurityServerHandler初始化");
        Object param = "";
        Map configs = config.getHandlerConfig();
        keyStoreFile = (String)configs.get("keyStoreFile");
        trustStoreFile = (String)configs.get("trustStoreFile");
        …//其它参数初始化   
    }
    …
}



客户端Handler开发

客户端Handler可以是任何JAX-RPC兼容的Handler处理器。比如AXIS Handler实现或者SUN 提供的JAX-RPC Handler参考实现。这里使用后者来作为客户端Handler处理器。

客户端Handler和服务器端Handler原理一样,但处理过程完全相反。


例程9 客户端Handler(WSSecurityClientHandler.java)

package com.hellking.study.webservice;


//客户端Handler
public class WSSecurityClientHandler implements Handler
{      
       //密匙库相关信息  
        ...
       
        /**
         *处理请求
         *流程:数字签名-->加密-->把Document转换成SOAP消息。
         */        
        public boolean handleRequest(MessageContext messageContext) {
        
                System.out.println("开始处理请求。。。");
           …
                   WSSHelper.sign(doc, keyStoreFile, keyStoreType,
                keyStorePassword, keyAlias, keyEntryPassword);
                WSSHelper.encrypt(doc, trustStoreFile, trustStoreType,
trustStorePassword, certAlias);
                soapMessage = MessageConveter.convertDocumentToSOAPMessage(doc);
                soapMessageContext.setMessage(soapMessage);
            …
         System.out.println("处理请求完毕!");
        return true;
    }
   
    /**
     *处理响应
     *流程:解密-->身份验证-->删除WSS元素'把Document转换成SOAP消息。
     */
     public boolean handleResponse(MessageContext messageContext) {

            System.out.println("开始处理Web服务响应。。。");
       …
                WSSHelper.decrypt(doc, keyStoreFile, keyStoreType,
                        keyStorePassword, keyAlias, keyEntryPassword);               
               
                WSSHelper.verify(doc, trustStoreFile, trustStoreType, trustStorePassword);
                WSSHelper.removeWSSElements(doc);

               
                soapMessage = MessageConveter.convertDocumentToSOAPMessage(doc);
                                System.out.println("the final message is:");
                                soapMessage.writeTo(System.out);
                soapMessageContext.setMessage(soapMessage);
            …       
            System.out.println("处理响应完毕!");
        return true;
    }
    /**
     *初始化,主要是初始化一些相关参数。
     */
     public void init(HandlerInfo config) {
        …
    }
    …
}



部署服务器端Handler

为了使用Handler,需要在Web服务部署描述符中指定使用此Handler。Handler包含的初始化参数也在此描述,如例程10所示。


例程10 服务器端Handler部署代码

  <service name="PersonalTaxServicePort" provider="java:RPC">
  <parameter name="allowedMethods" value="*"/>
  <parameter name="className" value="com.hellking.study.webservice.PersonalTaxService"/>
  <parameter name="wsdlTargetNamespace" value="http://hellking.webservices.com/"/>
  <parameter name="wsdlServiceElement" value="PersonalTaxService"/>
  <parameter name="wsdlServicePort" value="PersonalTaxServicePort"/>
  <parameter name="wsdlPortType" value="PersonalTaxService"/>
  <requestFlow>
   <handler type="java:org.apache.axis.handlers.JAXRPCHandler">
    <parameter name="scope" value="session"/>
    <parameter name="className"
            value="com.hellking.study.webservice.WSSecurityServerHandler"/>
    <parameter name="keyStoreFile"
            value="K:\\jakarta-tomcat-5.0.16\\server.keystore"/>
    <parameter name="trustStoreFile"
            value="K:\\jakarta-tomcat-5.0.16\\server.truststore"/>
    <parameter name="certAlias" value="clientkey"/>
   </handler>
  </requestFlow>
  <responseFlow>
   <handler type="java:org.apache.axis.handlers.JAXRPCHandler">
    <parameter name="scope" value="session"/>
    <parameter name="className"
            value="com.hellking.study.webservice.WSSecurityServerHandler"/>
    <parameter name="keyStoreFile"
            value="K:\\jakarta-tomcat-5.0.16\\server.keystore"/>

    <parameter name="trustStoreFile"
            value="K:\\jakarta-tomcat-5.0.16\\server.truststore"/>
    <parameter name="certAlias" value="clientkey"/>
   </handler>
  </responseFlow>
  </service>
  


requestFlow表示Web服务PersonalTaxServicePort的请求处理Handler链。这里只有一个Handler,就是WSSecurityServerHandler。当Web服务请求到达PersonalTaxServicePort时,WSSecurityServerHandler的handleRequest方法将被自动调用。

注意:部署时,请改变Handler相关参数以和目标的Web服务一致,比如trustStoreFile的路径等。

调用测试

这里采用代理的方式来调用Web服务,先编写一个Web服务接口。


例程11 TaxServiceInterface

package com.hellking.study.webservice;

/**
*个人所得税Web服务。
*/
public interface TaxServiceInterface extends Remote
{
    public double getTax(double salary)throws java.rmi.RemoteException;
}



WSSClient客户端程序是通过代理的方式来访问Web服务的。由于要使用Handler,所以在访问前通过registerHandlers()方法注册了WSSecurityClientHandler,并且初始化了WSSecurityClientHandler的相关参数。当然,JAX-RPC"参考实现"还支持在Web服务客户端配置文件中描述Handler信息,这样就不需要在客户端代码中对Handler进行注册了,你可以参考相关文档。


例程12 测试客户端程序(WSSClient)

package com.hellking.study.webservice;

...
/**
*调用需要验证的Web服务
*/
public class WSSClient
{
    static    final double salary=5000;
    public static void main(String [] args)
    {
        try {
            //服务端的url,需要根据情况更改。           
            String endpointURL = "http://localhost:8080/axis/services/PersonalTaxServicePort";
            String wsdlURL=endpointURL+"?wsdl";
            java.net.URL targetURL= new java.net.URL(wsdlURL);
            String nameSpaceUri = "http://hellking.webservices.com/";
            String svcName = "PersonalTaxService";       
            String portName = "PersonalTaxServicePort";

            ServiceFactory svcFactory = ServiceFactory.newInstance();

            Service svc = svcFactory.createService(targetURL, new QName(nameSpaceUri, svcName));
            //cfg表示客户端的配置信息。
            java.util.HashMap cfg = new java.util.HashMap();
           
            cfg.put("keyStoreFile", "client.keystore");           
            cfg.put("trustStoreFile", "client.truststore");           
            cfg.put("certAlias", "changeit");
           
            Class hdlrClass = com.hellking.study.webservice.WSSecurityClientHandler.class;
           
            java.util.List list = svc.getHandlerRegistry().
           
                           getHandlerChain(new QName(nameSpaceUri, portName));
           
            list.add(new javax.xml.rpc.handler.HandlerInfo(hdlrClass, cfg, null));
           
             registerHandlers (svc);
           
             TaxServiceInterface myProxy =
               ( TaxServiceInterface) svc.getPort(new QName(nameSpaceUri, portName),
                 TaxServiceInterface.class);      
              double ret=myProxy.getTax(5000);
            System.out.println("使用HTTP协议来作为Web服务的传输协议!");           
            System.out.println("已经成功调用。请参看服务端的输出!");
            System.out.println("输入工资"+salary+"元,应交个人所得税:"+ret);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //注册Handler
    private static void registerHandlers ( Service service )
        throws javax.xml.rpc.ServiceException {
       
        java.util.HashMap cfg = new java.util.HashMap();
           
            cfg.put("keyStoreFile", "client.keystore");           
            cfg.put("trustStoreFile", "client.truststore");           
            cfg.put("certAlias", "changeit");
           
        /*
        * 封装客户端Handler到HandlerInfo 中,然后添加到Handler链中。
        */
    javax.xml.rpc.handler.HandlerInfo info = new javax.xml.rpc.handler.HandlerInfo
    (com.hellking.study.webservice.WSSecurityClientHandler.class, cfg, null );
        java.util.ArrayList handlerList = new java.util.ArrayList();
        handlerList.add(info);
       
        /*
        * 获得Handler注册
        */
        javax.xml.rpc.handler.HandlerRegistry handlerRegistry = service.getHandlerRegistry();
       
        /*
        * 把Handler添加到所有的port中。
        */
        java.util.Iterator portIterator = service.getPorts();
        while ( portIterator.hasNext()) {
            Object obj=portIterator.next();
        QName portName = (QName) obj;
        handlerRegistry.setHandlerChain(portName, handlerList);
        }
    }
   
}



注意:由于客户端使用了SUN公司提供的"JAX-RPC参考实现",所以必须把jaxrpc-impl.jar包设置在CLASSPATH环境变量中,并且不要把axis.jar设置在客户端CLASSPATH环境变量,否则会出现ClassCastException异常。这是因为axis也是JAX-RPC的实现,如果它在CLASSPATH环境变量中,当调用:

ServiceFactory svcFactory = ServiceFactory.newInstance()方法时,就可能初始化一个axis的ServiceFactory 实现。

本文源代码中client目录下wss-client.bat文件包含了执行WSSClient脚本,修改了部分环境变量参数后,才能执行。

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=667538
分享到:
评论

相关推荐

    axis1.4webservices开发框架

    5. **安全与性能优化**: Axis1.4支持WS-Security(Web Services Security)标准,允许添加安全层如数字签名和加密。同时,还可以通过调整各种设置和缓存策略来优化性能。 总的来说,Axis1.4提供了一套完整的解决...

    java axis Webservices实例

    - **安全性**:可以通过添加安全层,如 SSL/TLS 加密,WS-Security(Web Services Security)来保护 Web 服务。 - **性能**:可以调整并发连接数、缓存策略等,以提高服务响应速度和整体性能。 7. **实战演练** ...

    webservices调用方法

    【webservices调用方法】与【TOMCAT+AXIS进行WEBSERVICE开发的配置和HELLOWORLD程序】相关的知识点: 1. **Web Services**:Web Services是一种通过网络进行通信的软件,允许不同系统间的互操作性。它们使用标准的...

    Develop Web Services With Apache Axis

    3. **如何使用WSS4J加密和签名SOAP消息**:WSS4J(Web Services Security for Java)是Apache的一个子项目,专门用于提供Web服务的安全功能。本书详细讲解了如何利用WSS4J来实现SOAP消息的加密和签名,从而保障数据...

    WebServices+SSL+Oracle XE+AXIS

    在本文中,我们将专注于如何使用AXIS这一开源Web服务框架来快速开发Web Services,并结合Oracle XE数据库以及SSL(Secure Sockets Layer)进行安全的通信。 首先,让我们详细了解一下SSL。SSL是一种网络安全协议,...

    西北工业大学软件工程WebServices实验报告

    **西北工业大学软件工程WebServices实验报告** Web Services是一种基于互联网的、平台独立的软件接口,它允许不同系统之间进行通信和交互。这个实验报告详细涵盖了Web Services的核心概念、技术栈以及在软件工程中...

    webservices例子

    这个“webservices例子”是一个使用Axis2框架进行Web服务应用测试的小实例。让我们深入探讨一下Web服务和Axis2框架的相关知识点。 1. Web服务基础: - **SOAP(Simple Object Access Protocol)**:Web服务通常...

    Axis2 Eclipse WebService插件

    4. **WSDL支持**:Axis2提供了强大的WSDL(Web Services Description Language)支持,可以自动生成或从现有WSDL文件中创建服务。 5. **数据绑定**:Axis2与多种数据绑定框架兼容,如Axiom、JAXB和XMLBeans,方便将...

    WebServices With Apache Axis.pdf

    - **WS-Security**:Axis支持WS-Security标准,提供了安全的Web服务,包括身份验证、加密和数字签名。 五、维护和调试 使用Axis的管理控制台,可以方便地监控服务状态,查看日志,以及进行故障排除。对于复杂的错误...

    WebServices开发文档[收集].pdf

    - Web Services的安全性非常重要,可能涉及的身份验证、加密、消息完整性和防止重放攻击等。常见的安全标准有WS-Security、WS-I BP(Basic Profile)等,它们提供了一套规范来确保Web Services的安全通信。 7. **...

    JAVA访问WebServices接口的简单实例,android可用

    在Java编程语言中,访问Web Services接口是一项常见的任务,特别是在构建Android应用时,因为Web Services提供了数据交换和远程调用功能。本实例将探讨如何在Java中实现这一过程,特别适用于Android开发。以下是一个...

    webservices 博客图片

    【标题】:Web服务(Webservices)技术详解 【描述】:Web服务是一种基于互联网的、使用标准协议(如HTTP)进行通信的技术,它允许不同的应用程序之间进行数据交换和功能共享。本博客图片集主要涵盖了Web服务的概念...

    Developing Web Services with Apache Axis2

    ### 开发Web服务使用Apache Axis2的关键知识点 #### 核心概念:Web服务与Apache Axis2 - **Web服务**是一种跨操作系统、硬件/软件平台的机制,它封装了一个平台特定的应用程序作为服务,该服务可以通过标准的HTTP...

    Webservices创建以及发布

    3. 包装为Web服务:使用Apache CXF、JAX-WS(Java API for XML Web Services)、 Axis2等工具将实现的服务打包成Web服务。 四、发布Web服务 1. 部署服务:将编译后的Web服务部署到Web服务器或应用服务器上,如...

    WebService详细解析(axis,xfire,cxf,授权认证加密解密)

    AXIS作为WebService服务器端和客户端的开发工具,使得开发者能够快速创建和消费Web Services。 1. AXIS简介 AXIS提供了简单的API和命令行工具,用于创建、部署和调用Web Services。它支持多种协议和数据绑定机制,...

    Developing Web Services with Apache CXF and Axis2_3rd Edition

    ### 开发Web服务:使用Apache CXF与Axis2(第三版) #### 一、书籍概述 本书《开发Web服务:使用Apache CXF与Axis2》是针对希望学习如何使用Java创建Web服务的专业人士所编写的实用教程。作者Kent Kai Ok Tong以...

    Web Services实验指导书

    - **UDDI**(统一描述、发现和集成):一个标准的目录服务,用于发布和查找Web Services。 2. **Web Services开发流程** - **服务创建**:使用编程语言(如Java、.NET等)创建提供服务的代码。 - **WSDL生成**:...

    WebServices远程服务调用案例

    - **Apache Axis**:一个开源的Java库,用于生成和部署WebServices,它简化了WSDL的生成和SOAP消息的处理。 - **JAX-WS (Java API for XML Web Services)**:Java平台的标准API,用于创建和消费WebServices。 - *...

    Web Services 系统集成 信息管理系统 流动人口 数据采集 日志跟踪.docx

    Axis是一个开源的Web Services 工具,它简化了Web Services 的开发和部署过程,支持WSDL的生成和解析,使得服务的创建和调用更加便捷。 综上所述,基于Web Services 的流动人口管理系统设计充分利用了Web Services ...

Global site tag (gtag.js) - Google Analytics