`

建立安全的AXIS服务(下)

    博客分类:
  • AXIS
阅读更多

四、使用WS-Security规范对信息进行加密与身份认证
    
我们打算用Handler结合WSSecurity实现Web服务安全
    
设想流程:用WSClientRequestHandler.java位于客户端对客户端发出的XML文档进行加密  WSServerRequestHandler.java位于服务器端对客户端发出的加密后的XML文档进行解密
WSServerResponseHandler.java
位于服务器端对服务器端返回的XML文档进行加密
WSClientResponseHandler.java
位于客户端对服务器端返回的XML文档进行解密
                
 1
、使用ISNetworks安全提供者,ISNetworks实现了RSA加密、解密算法。
    
当然,你也可以使用其它的安全提供者,并且可以使用不同的加密算法。
    ISNetworks
相关包ISNetworksProvider.jar。拷贝到%TOMCAT_HOME%     \webapps\axis\WEB-INF\lib
    
 2
Trust Services Integration Kit提供了一个WS-Security实现。你可以从http://www.xmltrustcenter.org获得相关库文件,分别是ws-security.jartsik.jarws-security.jar中包含一个WSSecurity类,我们使用它来对XML进行数字签名和验证,加密与解密。同样拷贝到%TOMCAT_HOME%\webapps\axis\WEB-INF\lib

 3
、创建密匙库和信任库。(见上文,一模一样!)
     
 4
、框架结构
    WSClientHandler.java  //
基类,包含了一些公用方法
    WSClientRequestHandler.java //
继承于WSClientHandler.java,调用WSHelper.java对客户端发出的XML文档进行加密
    WSClientResponseHandler.java //
继承于WSClientHandler.java,调用WSHelper.java对服务器端返回的XML文档进行解密
    WSServerHandler.java //
基类,包含了一些公用方法
    WSServerRequestHandler.java //
继承于WSServerHandler.java,调用WSHelper.java对客户端发出的加密后的XML文档进行解密
    WSServerResponseHandler.java//
继承于WSServerHandler.java,调用WSHelper.java对服务器端返回的XML文档进行加密
    WSHelper.java //
核心类,对SOAP消息签名、加密、解密、身份验证
    MessageConverter.java  //
帮助类,DocumentSOAP消息互相转换
  
 5
、具体分析(在此强烈建议看一下tsik.jarAPI
    WSHelper.java 

    public class WSHelper {
        
static String PROVIDER="ISNetworks";//JSSE安全提供者。
  
//添加JSSE安全提供者,你也可以使用其它安全提供者。只要支持DESede算法。这是程序里动态加载还可以在JDK中静态加载
        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();//ws-security.jar中包含的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(
168new 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相关的元素。
        }

}



   WSClientHandler.java

   //继承自org.apache.axis.handlers.BasicHandler即AXIS内在的
   public class WSClientHandler extends BasicHandler{
  
protected String keyStoreFile ;
  
protected  String keyStoreType ="JKS";//默认
  protected String keyStorePassword ;
  
protected String keyAlias ;
  
protected String keyEntryPassword ;
  
protected String trustStoreFile ;
  
protected String trustStoreType = "JKS";//默认
  protected String trustStorePassword ;
  
protected String certAlias ;

  
public void setInitialization(String keyStoreFile,String keyStoreType,String keyStorePassword,
                 String keyAlias,String keyEntryPassword,String trustStoreFile,
                 String trustStoreType,String trustStorePassword,String certAlias){
  
this.keyStoreFile=keyStoreFile;
  
this.keyStoreType=keyStoreType;
  
this.keyStorePassword=keyStorePassword;
  
this.keyAlias=keyAlias;
  
this.keyEntryPassword=keyEntryPassword;
  
this.trustStoreFile=trustStoreFile;
  
this.trustStoreType=trustStoreType;
  
this.trustStorePassword=trustStorePassword;
  
this.certAlias=certAlias;
}
  
public void setInitialization(String keyStoreFile,String keyStorePassword,
                String keyAlias,String keyEntryPassword,String trustStoreFile,
                String trustStorePassword,String certAlias){
  
this.keyStoreFile=keyStoreFile;
  
this.keyStorePassword=keyStorePassword;
  
this.keyAlias=keyAlias;
  
this.keyEntryPassword=keyEntryPassword;
  
this.trustStoreFile=trustStoreFile;
  
this.trustStorePassword=trustStorePassword;
  
this.certAlias=certAlias;
}
  
public void invoke(MessageContext messageContext) throws AxisFault {//在这个方法里对XML文档进行处理
    
//do nothing now!
  }
  
public void onFault(MessageContext msgContext) {
    System.out.println(
"处理错误,这里忽略!");
        }
}


  
  WSClientRequestHandler.java
 

  public class WSClientRequestHandler extends WSClientHandler{
  
public void invoke(MessageContext messageContext) throws AxisFault {
    
try {

     SOAPMessage soapMessage 
= messageContext.getMessage();
     Document doc 
= MessageConverter.convertSoapMessageToDocument(soapMessage); //soapMessage转换为Document
     WSHelper.sign(doc, keyStoreFile, keyStoreType,keyStorePassword, keyAlias, keyEntryPassword); //数字签名
     WSHelper.encrypt(doc, trustStoreFile, trustStoreType, trustStorePassword, certAlias); //加密
     soapMessage = MessageConverter.convertDocumentToSOAPMessage(doc); 
//处理后的Document再转换回soapMessage
     messageContext.setMessage(soapMessage);
     } 
catch (Exception e){
     System.err.println(
"在处理响应时发生以下错误: " + e);
      e.printStackTrace();  }
        }



  WSClientResponseHandler.java
 

  public class WSClientResponseHandler extends WSClientHandler{
  
public void invoke(MessageContext messageContext) throws AxisFault {
    
try {

            SOAPMessage soapMessage 
=  messageContext.getCurrentMessage();
            Document doc 
= MessageConverter.convertSoapMessageToDocument(soapMessage);

        WSHelper.decrypt(doc, keyStoreFile, keyStoreType,
                            keyStorePassword, keyAlias, keyEntryPassword);
//解密

            WSHelper.verify(doc, trustStoreFile, trustStoreType, trustStorePassword);
//验证
            WSHelper.removeWSSElements(doc);
            soapMessage 
= MessageConverter.convertDocumentToSOAPMessage(doc);
            messageContext.setMessage(soapMessage);
    } 
catch (Exception e){
            e.printStackTrace();
            System.err.println(
"在处理响应时发生以下错误: " + e);
                         }

        }


   
   WSServerHandler.java 
   

   public class WSServerHandler extends BasicHandler{
  
protected String keyStoreFile ;
  
protected  String keyStoreType ="JKS";//默认
  protected String keyStorePassword ;
  
protected String keyAlias ;
  
protected String keyEntryPassword ;
  
protected String trustStoreFile ;
  
protected String trustStoreType = "JKS";//默认
  protected String trustStorePassword ;
  
protected String certAlias ;

  
public void invoke(MessageContext messageContext) throws AxisFault {
    
//do nothing now!
  }
  
public void onFault(MessageContext msgContext) {
    System.out.println(
"处理错误,这里忽略!");
        }
  
public void init() { //初始化,从配置文件server-config.wsdd中读取属性
    keyStoreFile = (String)getOption("keyStoreFile");
    
if(( keyStoreFile== null) )
      System.err.println(
"Please keyStoreFile configured for the Handler!");
    trustStoreFile 
= (String)getOption("trustStoreFile");
     
if((  trustStoreFile== null) )
    System.err.println(
"Please trustStoreFile configured for the Handler!");
    keyStorePassword 
= (String)getOption("keyStorePassword");
     
if(( keyStorePassword== null) )
    System.err.println(
"Please keyStorePassword configured for the Handler!");
    keyAlias 
= (String)getOption("keyAlias");
     
if(( keyAlias== null) )
    System.err.println(
"Please keyAlias configured for the Handler!");
    keyEntryPassword 
= (String)getOption("keyEntryPassword");
     
if(( keyEntryPassword== null) )
    System.err.println(
"Please keyEntryPassword configured for the Handler!");
    trustStorePassword 
= (String)getOption("trustStorePassword");
     
if(( trustStorePassword== null) )
    System.err.println(
"Please trustStorePassword configured for the Handler!");
    certAlias 
= (String)getOption("certAlias");
    
if ((certAlias==null))
        System.err.println(
"Please certAlias configured for the Handler!");
    
if ((getOption("keyStoreType")) != null)
       keyStoreType 
= (String)getOption("keyStoreType");
    
if ((getOption("trustStoreType")) != null)
       trustStoreType 
= (String)getOption("trustStoreType");
    }

    
    
    WSServerRequestHandler.java 

    public class WSServerRequestHandler extends WSServerHandler{
  
public void invoke(MessageContext messageContext) throws AxisFault {
    
try {
      SOAPMessage msg 
= messageContext.getCurrentMessage();
            Document doc 
= MessageConverter.convertSoapMessageToDocument(msg);
            System.out.println(
"接收的原始消息:");
           msg.writeTo(System.out);
        WSHelper.decrypt(doc, keyStoreFile, keyStoreType,
                            keyStorePassword, keyAlias, keyEntryPassword);
//解密

            WSHelper.verify(doc, trustStoreFile, trustStoreType, trustStorePassword);
//验证
            WSHelper.removeWSSElements(doc);
            msg 
= MessageConverter.convertDocumentToSOAPMessage(doc);
            System.out.println(
"怀原后的原始消息:");
            msg.writeTo(System.out);
            messageContext.setMessage(msg);
    } 
catch (Exception e){
            e.printStackTrace();
            System.err.println(
"在处理响应时发生以下错误: " + e);
                         }

        }
}   


     
     WSServerResponseHandler.java

     public class WSServerResponseHandler extends WSServerHandler{
  
public void invoke(MessageContext messageContext) throws AxisFault {
    
try {

     SOAPMessage soapMessage 
= messageContext.getMessage();
       System.out.println(
"返回的原始消息:");
         soapMessage.writeTo(System.out);
      Document doc 
= MessageConverter.convertSoapMessageToDocument(soapMessage);

        WSHelper.sign(doc, keyStoreFile, keyStoreType,
          keyStorePassword, keyAlias, keyEntryPassword);
//数字签名
       WSHelper.encrypt(doc, trustStoreFile, trustStoreType,//加密
        trustStorePassword, certAlias);

       soapMessage 
= MessageConverter.convertDocumentToSOAPMessage(doc);
       System.out.println(
"返回的加密后的消息:");
       soapMessage.writeTo(System.out);
       messageContext.setMessage(soapMessage);
        } 
catch (Exception e){
        System.err.println(
"在处理响应时发生以下错误: " + e);
         e.printStackTrace();
         }

        }
}



6
、应用
   
为方便使用,把上述文件打包为ws-axis.jar,放入%TOMCAT_HOME%\webapps\axis\WEB-INF\lib
   
   1
)把HelloWorld重新部署一次,在server-config.wsdd中修改如下部署代码。

       <service name="HelloWorld" provider="java:RPC">
         
<parameter name="allowedMethods" value="*"/>
         
<parameter name="className" value="HelloWorld"/>
         
<requestFlow>
           
<handler type="soapmonitor"/>
           
<handler type="java:com.ronghao.WSAxis.WSServerRequestHandler">
              
<parameter name="keyStoreFile" value="f:\server.keystore"/>
              
<parameter name="trustStoreFile" value="f:\server.truststore"/>
              
<parameter name="keyStorePassword" value="changeit"/>
              
<parameter name="keyAlias" value="Server"/>
              
<parameter name="keyEntryPassword" value="changeit"/>
              
<parameter name="trustStorePassword" value="changeit"/>
              
<parameter name="certAlias" value="clientkey"/>
           
</handler>
        
</requestFlow>
        
<responseFlow>
           
<handler type="soapmonitor"/>
           
<handler type="java:com.ronghao.WSAxis.WSServerResponseHandler">
              
<parameter name="keyStoreFile" value="f:\server.keystore"/>
              
<parameter name="trustStoreFile"  value="f:\server.truststore"/>
              
<parameter name="keyStorePassword" value="changeit"/>
              
<parameter name="keyAlias" value="Server"/>
              
<parameter name="keyEntryPassword" value="changeit"/>
              
<parameter name="trustStorePassword" value="changeit"/>
              
<parameter name="certAlias" value="clientkey"/>
           
</handler>
        
</responseFlow>
     
</service>


     
    2)
修改客户端程序 TestClient.java(修改的部分已标出,记着导入ws-axis.jar

    import javax.xml.namespace.QName;
    
import org.apache.axis.client.Call;
    
import org.apache.axis.client.Service;
    
import com.ronghao.WSAxis.*;
    
    
public class WSSClient1
{
    
public static void main(String [] args)
    {
        
try {
                
//服务端的url,需要根据情况更改。
            String endpointURL = "http://localhost:8080/axis/services/HelloWorld";
            Service svc 
= new Service();

            WSClientHandler handler
=new WSClientRequestHandler();
//注意新加的HANDLER
            handler.setInitialization("f:/client.keystore","changeit","Client","changeit",
                
"f:/client.truststore","changeit","serverkey");//初始化
            WSClientHandler handlee=new WSClientResponseHandler();
//注意新加的HANDLER
            handlee.setInitialization("f:/client.keystore","changeit","Client","changeit",
                
"f:/client.truststore","changeit","serverkey");//初始化
                     Call call =(Call)svc.createCall();
                     call.setClientHandlers(handler,handlee);
//添加Handler
                     call.setTargetEndpointAddress(new java.net.URL(endpointURL));
                     call.setOperationName(
new QName("sayHello"));

                     String result 
= (String) call.invoke( new Object [] {});
                     System.out.println(
"the result"+result);

        } 
catch (Exception e) {
                e.printStackTrace();
        }
    }


}


   
运行的时候http://localhost:8080/axis/SOAPMonitor中看到的请求的XML就已加密!
   
总结
   
这里对代码的解释是不够的,很多概念没有提到。建议你最好看tsik.jarAXISAPI深入了解。另外对ws-axis.jar的加解密实现打算运用apachewss4j,相关网址http://ws.apache.org/ws-fx/wss4j/。不过这个东西也应该够用了暂时。

 

分享到:
评论

相关推荐

    axis2jar包

    在Java世界中,Axis2以其强大的功能和灵活性而闻名,它建立在 Axis1 的基础上,改进了性能并引入了许多新特性。Axis2的核心组件是以模块化的方式构建的,这使得开发者可以根据需要选择和配置特定的功能。 1. **Web...

    axis JAR包,axis 完整包

    Axis是一款开源的Web服务开发工具,它主要用于创建和部署SOAP(简单对象访问协议)服务,同时也支持WS-I(Web服务互操作性)规范。在Java环境中,Axis使得开发者能够轻松地将现有的Java类转换为Web服务,或者消费由...

    Webservice之Axis高级编程

    4. **AXIS第四课:AXIS高级应用,建立安全的AXIS服务** 安全性是Web服务不可或缺的一部分。在这一课,我们将探讨如何在Axis中实现安全性,包括使用HTTPS协议、WS-Security规范(如数字签名和加密)来保护数据传输的...

    axis2-1.4插件

    这个框架是建立在 Axis1 的基础上,但设计更加模块化和可扩展。Axis2-1.4 版本是该框架的一个稳定版本,提供了许多改进和新特性。 1. **模块化设计**:Axis2 的模块化设计使得它可以根据需求来选择和配置不同的功能...

    axis2-1.8.0apache-cxf-3.4.4.rar

    标签中的"soap axis2 apache java webservice"揭示了这些工具和技术主要用于处理Java环境下的SOAP Web服务。在实际开发中,开发者通常会使用Axis2来创建服务,然后使用CXF来提供更高级的功能,如REST支持和与其他...

    axis2-1.5.5-bin.zip

    5. **强大的WS-*支持**:Axis2对诸如WS-Security、WS-ReliableMessaging等WS-*标准有良好的支持,确保了Web服务的安全性和可靠性。 6. **丰富的API和工具**:提供了丰富的Java API以及命令行工具,方便开发者进行...

    APACHE AXIS2

    Apache Axis2是Apache软件基金会下的一款开源、高性能的Web服务框架,它支持SOAP协议,并且兼容JAX-WS(Java API for XML Web Services)规范。Axis2是Apache Axis的一个重大升级版本,提供了更丰富的功能、更高的...

    AXIS2+Myeclipse实现WebService数据库存储简单实例

    为了实现这个实例,开发者首先需要在Myeclipse中创建一个新的AXIS2 Web服务项目,然后导入`webbook.sql`并执行来建立数据库环境。接着,编写服务器端代码,定义服务接口和实现,确保它们能够正确连接到数据库并执行...

    java 调用https webservice实例及axis包

    注意,由于是HTTPS,所以在调用前可能需要建立SSL连接,处理身份验证等安全操作。 5. **处理异常**:在调用过程中,可能会遇到SSL相关的异常,如`CertificateException`, `KeyManagementException`, `...

    axis安讯士摄像头rtsp视频流数据获取程序

    "Axis安讯士摄像头rtsp视频流数据获取程序" 是一个专用于与Axis品牌安讯士摄像头进行交互的软件程序,主要功能是获取并处理来自摄像头的实时传输协议(RTSP)视频流数据。Axis安讯士是知名的专业网络摄像头制造商,...

    axis开发webservices.doc

    本文介绍了使用Axis2开发Web服务的基本流程,从获取和部署Axis2到建立自定义Web服务的过程。通过对SOAP请求的解析和响应的生成,我们可以实现对特定数据的处理。此外,通过直接操作系统目录级的方式,可以更加灵活地...

    axis2学习资料Java示例代码.zip

    2. **客户端代码**:客户端代码通常包含一个或多个调用服务的方法,使用Axis2的Stub或ServiceClient类来建立与服务的连接并发送请求。它可能还包括了处理响应和异常的部分。 3. **依赖包axis2**:这个可能是一个...

    WebServices With Apache Axis.pdf

    总结,Apache Axis为Web服务的开发提供了强大的支持,从简单的服务创建到复杂的安全配置,都提供了一套完整的解决方案。通过熟练掌握Axis的使用,开发者可以轻松构建起跨平台的分布式应用程序,实现系统的无缝连接。

    建立Web服务.rar

    综上所述,建立Web服务是一个涉及接口设计、实现、发布、测试、安全和维护等多个环节的过程。选择合适的技术栈、遵循最佳实践并注重安全性,将有助于构建高效、可靠的Web服务,实现跨系统的数据交换和业务协同。

    axis2大讲堂word版

    通过这个“Axis2大讲堂”,你可以逐步建立起对Web服务开发和Axis2框架的深入理解,从而提高你的开发技能和项目实施能力。无论是初学者还是有经验的开发者,都能从中受益匪浅,提升自己的专业素养。

    基于soap over jms 的websphere mq与axis2的实现

    4. **连接 Axis2 和 WebSphere MQ**:编写或配置 Axis2 应用程序,使其能够通过JMS API与WebSphere MQ建立连接,发送和接收消息。 5. **测试和调试**:通过发送SOAP请求到Axis2服务,验证消息是否正确地通过...

Global site tag (gtag.js) - Google Analytics