`
eddysheng
  • 浏览: 111965 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

动态的为web service soap消息增加验证规则

阅读更多

在我们当前的 SaaS 系统中 request response 的验证包括两部分,一部分为 jaxb schema 验证,一部分为局部业务规则约束的验证(通过在 service 实现中侵入代码进行验证)。

 

我一直觉得当前的验证(非数据库相关)不是很灵活,因此我就做了一个动态的验证框架,实现思路如下:

在我们的系统中每一个 service 对应多个 operation ,每一个 operation 既是一个 request/response 处理者。我们的验证是针对 request/response ,因此需要建表结构(示意)如下:

Vaidations

OperationID

操作 id

Type

类型 request/response

ValidateKey

验证的 key ,即 request/response xpath 路径

ValidateRule

匹配 validateKey 的值 de 验证规则,利用正则表达式

所有的验证规则都会进行缓存以减少数据库操作。

 

在服务管理界面上可以动态的增加 / 删除 / 修改验证规则,在服务的调用时增加 SoapHandler ,执行过程如下:

1.  SOAPMessageContext 中获取请求 URL ,通过 URL 获取 OperationID

2.   根据 operationID 从缓存中获取请求或响应对应的所有验证规则。

3.  循环验证开始

4.  根据 ValidateKey SOAPMessageContext 中获取请求 / 响应中对应的值。

5.  匹配 ValidateRule 对应的正则表达式,如果不匹配,则 fail-fast 直接抛出运行时异常;匹配则验证下一个。

6.  循环验证结束。

 

数据操作以及正则表达式验证大家可以自己实现,下面简单写了一个 handler ,只是为了验证通过 xpath 获取 soap request 中的 value ,如果有兴趣大家可以自己完善。

 

package com.hp.test.cxf.handlers;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.xml.sax.InputSource;


public class ValidationHandler implements SOAPHandler<SOAPMessageContext> {

	public Set<QName> getHeaders() {
		// TODO Auto-generated method stub
		return null;
	}

	public void close(MessageContext arg0) {
		// TODO Auto-generated method stub
		
	}

	public boolean handleFault(SOAPMessageContext arg0) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean handleMessage(SOAPMessageContext smc) {
		Boolean outboundProperty = (Boolean)smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
		if (outboundProperty.booleanValue()) {
			//System.out.println("Out:"+smc.toString());
	    	return true;
	    } else {
	    	try{
	    		//从缓存中获取此URL(operation)对应的所有验证规则
	    		//循环验证key-rule
	    		SimpleNamespaceContext nsContext = new SimpleNamespaceContext();  
	            nsContext.setNamespace("soapenv",  "http://schemas.xmlsoap.org/soap/envelope/"); // instead of "SOAP-ENV"  
	            nsContext.setNamespace("cxf",   "http://cxf.test.hp.com/"); 
		    	String name = getDataXpath(smc.getMessage(),
		    			"/soapenv:Envelope/soapenv:Body/cxf:Person/name/child::text()",
		    			nsContext);
		    	//if(!name.matchs(rule)){throw new RuntimeException("name is invalid!");}
		    	//循环结束
	    	}catch(Exception e){e.printStackTrace();}
	    	return true;
	    }
	}
	
	public String getDataXpath( SOAPMessage message, String expression, NamespaceContext nsContext )   
    		throws java.io.IOException, javax.xml.soap.SOAPException, javax.xml.xpath.XPathExpressionException {  
	    ByteArrayOutputStream out = new ByteArrayOutputStream();  
	    message.writeTo(out);  
	    InputSource inputSource = new InputSource(    
	        new ByteArrayInputStream(out.toByteArray())   
	    );  
	
	    XPathFactory factory    = XPathFactory.newInstance();  
	    XPath xPath             = factory.newXPath();  
	    if (nsContext != null) xPath.setNamespaceContext( nsContext );  
	        
	    XPathExpression xpathExpression = xPath.compile( expression );  
	    return xpathExpression.evaluate( inputSource );  
	}      
}
class SimpleNamespaceContext implements NamespaceContext {  
    private Map<String,String> map;  
    
    public SimpleNamespaceContext() {  
        map = new HashMap<String,String>();  
    }  
      
    public void setNamespace(  
        String prefix,  
        String namespaceURI  
    ){  map.put(prefix, namespaceURI); }  
      
    // !!! doesn't fully implement getNamespaceURI API spec !!!  
    public String getNamespaceURI(  
        String prefix  
    ){  return map.get(prefix); }  
      
    // !!! doesn't fully implement getPrefix API spec !!!  
    public String getPrefix( String namespaceURI ){  
        SinglePrefixCollector collector = new SinglePrefixCollector();  
        collectPrefixes( namespaceURI, collector );  
        return collector.getResult();  
    }  
   
    // !!! doesn't fully implement getPrefixes API spec !!!  
    public Iterator getPrefixes( String namespaceURI ){  
        MultiPrefixCollector collector = new MultiPrefixCollector();  
        collectPrefixes( namespaceURI, collector );  
        return collector.getResult();  
    }  
   
    protected void collectPrefixes( String namespaceURI, PrefixCollector collector  ) {  
        Iterator<String>  iterator = map.keySet().iterator();   
        while( iterator.hasNext() ) {  
            String prefix = iterator.next();  
            if ( getNamespaceURI(prefix).equals(namespaceURI) ) {  
                boolean addMore = collector.addPrefix(prefix);  
                if(! addMore ) break;  
            }  
        }  
    }  
   
    protected interface PrefixCollector {  
        // template method for subclasses  
        // return: true - continue collecting; false - stop collecting.  
        boolean addPrefix(String prefix);  
    }  
   
    static protected class SinglePrefixCollector implements PrefixCollector {  
        private String prefix = null;  
        // returns false to stop further additions as it can only hold one prefix  
        public boolean addPrefix( String prefix ) { this.prefix = prefix; return false; }  
        public String getResult(){ return prefix; }  
    }  
   
    static protected class MultiPrefixCollector implements PrefixCollector {  
        private List<String> prefixes = new ArrayList<String>();  
        // returns true as it can hold more than one prefix  
        public boolean addPrefix( String prefix ) { prefixes.add(prefix); return true; }  
        public Iterator getResult() { return prefixes.iterator(); }  
    }  
} 
 

 

请求的 wsdl 如下

 

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cxf="http://cxf.test.hp.com/">
   <soapenv:Header/>
   <soapenv:Body>
      <cxf:Person>
         <name>1</name>
         <address>2</address>
         <phone>3</phone>
         <email>eddis</email>
         <addresslist>
            <address>
               <address>8</address>
               <test>9</test>
            </address>
         </addresslist>
      </cxf:Person>
   </soapenv:Body>
</soapenv:Envelope>
 

 

 

分享到:
评论

相关推荐

    Web Service SOAP Client set SOAP Header

    当涉及到Web Service客户端与服务器之间的交互时,有时需要在SOAP消息中添加额外的信息,例如身份验证或安全凭证,这就是SOAP Header的作用。SOAP Header是SOAP Envelope的一部分,它允许扩展和自定义消息处理。 在...

    Web Services SOAP Header 验证的例子

    为了实现这种验证机制,开发人员可能需要熟悉WSDL(Web Service Description Language)文件,它定义了Web服务的接口和消息结构,包括SOAP Header的使用。此外,了解SOAP协议、XML和可能的安全框架(如WS-Security)...

    《C++ Builder 6 SOAP Web Service》配套光盘

    总之,《C++ Builder 6 SOAP Web Service》配套光盘为读者提供了一套完整的SOAP Web服务开发资源,无论你是初学者还是有经验的开发者,都能从中受益,提升你的C++ Builder 6和SOAP技术能力。通过实践书中的示例和...

    SOAP安全验证全套示例

    `Demo XML Web Service for Windows Authentication`这个项目展示了如何配置和使用SOAP Header进行Windows身份验证。这涉及到在SOAP请求中包含特定的认证头信息,以便服务器能够验证客户端的身份。 2. **自定义身份...

    用SOAP标题验证的WEB service

    【标题】"用SOAP标题验证的WEB服务"涉及到的核心概念是Web服务安全性和SOAP消息头的应用,这在C#高级编程中是一个重要的实践案例。Web服务是一种通过互联网进行通信的应用程序接口,允许不同系统间的数据交换。在此...

    web service-soap ppt

    Web服务(Web Service)是一种基于互联网的、采用标准的XML(Extensible Markup Language)格式来交换数据的应用程序间通信方式。SOAP(Simple Object Access Protocol)是Web服务中最常见的一种消息协议,它允许...

    soap/Web Service客户端

    Web服务则是一种通过网络提供可重用功能的软件系统,通常使用SOAP作为消息传递机制。 在SOAP/Web服务客户端开发中,有几个关键知识点需要理解: 1. **SOAP消息结构**:SOAP消息由三个主要部分组成:Envelope、...

    基于SOAP消息组合变异的web服务漏洞测试

    基于SOAP消息组合变异的Web服务漏洞测试方法通过引入组合变异和特定的测试策略,为Web服务提供了一种更为全面和有效的漏洞检测手段。这种测试方法不仅可以提高测试的覆盖率,还能帮助开发者更快地识别和修复潜在的...

    浅谈SoapWeb Service架构及其应用

    总之,SOAP Web Service作为一种成熟且广泛采用的分布式应用程序模型,为企业和个人提供了高效、灵活的服务交互方式。随着技术的不断发展,尽管出现了RESTful API等新的服务架构,SOAP Web Service仍然在许多领域...

    web service ppt

    数据绑定是Web Service中的一个重要概念,它涉及到将XML消息转换为编程语言中的对象,反之亦然。WS-Security提供了Web Service的安全框架,确保数据在传输过程中的安全性。WS-Notification用于服务间的事件通知,而...

    Web Service 身份验证1

    在本文中,我们将探讨一种基于Web Service的身份验证方法,这种方法是通过SOAP Header来实现的。SOAP Header是一种在SOAP消息中包含附加信息的方式,可以用来传递安全、事务处理、路由等元数据。以下是对该主题的...

    Web+Service学习.doc

    SOAP 消息遵循一定的语法规则,如消息必须用 XML 编码,使用 SOAP Envelope 命名空间,并且不能包含 DTD 引用和 XML 处理指令。以下是一个基本的 SOAP 消息示例: ```xml &lt;soap:Envelope xmlns:soap=...

    C#Web Service C#Web Service C#Web Service

    6. **安全考虑**:Web Service的安全性是至关重要的,可以通过配置服务来实现基本的身份验证、消息认证、数据加密等。例如,使用WS-Security标准可以添加用户名令牌、数字签名和加密。 7. **高级特性**:除了基本的...

    SOAP webserivce 和 RESTful webservice 对比及区别

    相比之下,SOAP服务的安全控制通常涉及更复杂的XML消息验证和处理,因为所有的业务逻辑和安全信息都封装在SOAP消息中。这可能导致在现有的HTTP代理服务器上实现安全策略时遇到困难,因为代理可能无法直接解析和处理...

    使用 Spring-WS 完成的 Web Service (SOAP)

    Spring-WS 是一个基于 Java 的轻量级 Web Service 框架,专注于 SOAP 协议。这个框架使得开发者能够创建符合 W3C 标准的、契约优先的 Web Service 应用程序。在本篇文章中,我们将深入探讨如何使用 Spring-WS 实现 ...

    XML Web Service开发

    XML Web Service的安全性是关键问题,常见的安全措施包括SSL/TLS加密、WS-Security(Web Services Security)提供消息级安全,以及身份验证和授权机制。 七、Web Service的集成 Web Service常被用于系统集成,例如...

    Web_Service开发指南

    - **SOAP头验证**:可以在SOAP消息的头部添加安全信息,如数字签名、加密等,以增强消息的完整性和安全性。 - **SSL/TLS**:使用HTTPS协议来保护数据在传输过程中的安全,防止中间人攻击。 - **OAuth/OAuth2**:一种...

    调用Biztalk发布的web service演示

    首先,开发者创建一个BizTalk项目,定义需要暴露为Web服务的操作和消息类型。然后,使用BizTalk Orchestrator设计业务流程,将这些操作串联起来。一旦设计完成,可以通过BizTalk Administrator将编排部署到BizTalk...

    Web Service编程:用C#开发网络服务

    在服务类中,定义公共方法作为服务操作,这些方法将暴露为Web Service的方法供客户端调用。 2. **定义服务接口**: WSDL文件描述了Web Service的接口,包括服务地址、操作、输入/输出消息等。在ASMX中,编译后的...

    实现隐式和显式 SOAP 消息头

    在Java中,你可以使用JAX-WS(Java API for XML Web Services)来处理SOAP消息头。以下是一个简单的示例: 1. **创建消息监听器**: ```java import javax.xml.ws.handler.MessageContext; import javax.xml.ws....

Global site tag (gtag.js) - Google Analytics