技术开发 频道

企业SOA:“纵深防御”与“Endpoint”实施

【IT168 技术分析】随着2006年的结束,SOA从各大IT厂商推荐的概念变成了众多企业架构师需要实实在在勾勒的建设计划。并且建设的目的性一般都非常明确:“通过整合企业自身及合作方的各类技术资源,采用跨平台、跨产品的通用技术,把相关的相对分散的资源融合为一个逻辑的互联系统。” 

    从架构层次看,笔者倒是觉得ERP的概念似乎更有些生不逢时的感觉,不仅是各异的消息通信机制、开发组件技术,甚至于不同应用系统的业务功能也可以划在SOA整合的范围之内。抛开现有ERP产品包含的功能不谈,仅仅从“Enterprise Resource Planning”字面看SOA却是更好的“攒鸡毛凑掸子”的思路。也就是说,以往的ERP建设更类似以往的结构化设计,通过一个大而全的系统总体运筹企业,而SOA则是给整个企业IT资源计划提供了分步骤实施、迭代化设计的有力支持。 

    虽然建设的规模迥异,但是雷同的部分其实很多,如下: 

    (1)基本上统一采用XML Web Service作为Service封装技术。 

    (2)每个Web Service开发平台本身采用了非常先进的开发语言,即较新版本的.NET和Java开发语言。 

    (3)通过购买或者集成方式建立了强劲高效的企业服务总线(ESB, Enterprise Service Bus),并基于该总线完成了整个SOA交换环境的交易性、流程可配置性和访问控制等支撑服务。 

    (4)以Adapter方式接入每个Service Endpoint,并将Service Endpoint统一注册在服务注册器中。 

    (5)总体结构一般如下:


图:一般的SOA平台架构

不过在相关SOA的设计中由于XML Web Service本身处于HTPP + XML这种离线信息环境,因此很多以往在COM+、EJB很容易就能实现的控制能力被一定程度的弱化。因此为了达到与以往N-Tier企业分布式应用相同的IT控制能力,笔者认为需要从下面若干方面进行更深层次的技术突破。

    做好SOA的纵深防御 

    这里借鉴以往系统安全上常用的“纵深防御”(In Depth Defense)来说,虽然企业服务总线上可以设计一个统一的认证和授权控制系统。但是就像SOAP调用可以很容易地穿越防火墙一样,非法的SOAP调用一样很容易不经过企业服务总线到达每个具体的Service Endpoint上。如果这里不设防,对于一个企业级的SOA应用而言可以说埋下了很多日后安全问题的伏笔。这里笔者建议在设计上,SOA环境本身也要贯彻“纵深”的防御方法。


图:SAO架构中需要实施“纵深防御”的元素

    具体说明如下。 

    Service Registry:就像DNS等许多其他集中控制服务一样,Service Registry最起码要准备好应对如下两种方式的攻击:拒绝服务和毒化(就是篡改其配置内容,导致错误的Service路由或访问控制等)。 

    Service Endpoint:Service Endpoint作为与实际内部企业应用联结的纽带,除了可以实现信息交换外,访问控制也是设计上必须考虑的问题。而且为了适应企业安全规定和策略的修改,这部分Endpoint的访问控制或许还包括授权检查、流量控制也必须可以配置,并且这个配置不能依赖于Service Registry。当然,定义工作可以在Service Registry中进行,但是必须要保证其“推”到Service Endpoint后生效,否则就失去了“纵深防御”的意义。 

    Provider:Provider作为服务的提供者,如果设计不当,很容易被过度使用。 

    Adapter:Adapter本身一般仅仅和企业内部的Service交换信息,相对而言由于它是分散的,并且实际的处理能力一般瓶颈会限制在Service Registry和每个Service Endpoint后面的具体Service上,而Adapter自身一般也不管理实际的业务性信息,因此Adapter相对安全。只不过出于执行效率的考量,内部的Service可能运行于Load Balance上,但是Adapter却只是面向企业服务总线的单一组成,它的并发行会制约内部Service的服务效果,因此设计上除了考虑其功能实现外,并发情况下可能导致的可用性问题需要考虑。 

    外部服务访问接口:对于外部服务访问接口而言,则可以完全视为Web客户端。区分Internet、Intranet和内部代理远程Proxy访问、内部局域网用户访问等不同类型,通过在Web Server上定义访问规则来控制。由于现有JSP和ASP.NET平台均有不错的控制配置错误,考虑到系统整体的灵活性,建议这部分控制更多的由Web Server和Web 服务应用的配置部分完成。

    完成更“好”的Service Endpoint

    这里一个“好”字同时包括了多层的意思:“更好的”扩展性、“更好的”响应效率、还有上文提到的“更好的”访问控制等。笔者之所以在这里强调Service Endpoint,主要和所见的一些企业建设过程有关,很多企业通过.NET和Java提供的互操作特性,在没有对整体Endpoint做出比较慎重的规划后,很快地把许多以前的组件环境包装为XML Web Service版的Web组件——相对而言非常大的精力放在企业服务总线上。虽然这会在企业SOA的初期快速地取得成效,并且完成一个适于企业Then and There的SOA环境,但说到底企业SOA毕竟不是为了技术而技术,更多的是为了后续的业务。这里每个后续的业务就是由不断加入的Service Endpoint提供的,如果这一层设计上有缺陷或者缺乏扩展的话,以后修改的代价就会很大。 

    在技术实现上,Endpoint一般会采用WSDL的方式描述如下五类元素: 

    (1)Types:包括可由Web Server守法的消息Schema定义,一般是XSD(XML Schema)。 

    (2)Message:主要是充当消息和消息定义之间的关联的交叉引用。 

    (3)PortType:定义了XML Web Service可以对外公开的Service Interface。 

    (4)Binding:将PortType与具体的协议进行关联。 

    (5)Service:定义了XML Web Service对外服务的一组Port的集合。 

    虽然XML信息本身是Schema比较容易扩展的,但是每个企业SOA特定版本中Endpoint所能说明的,或者是企业服务总线所能理解的内容,如果采取编码方式完成还是非常有限的,设计上需要配置一个非常灵活的结构。 

    当然,对于控制类处理,相信各位架构师可以采用Intercepting Filter模式完成。如下图:


图:Intercepting Filter模式图

    具体说明如下: 

    (1)每个Web Service调用时,都需要把其调用内容通过Filter Chain进行一组筛选。 

    (2)每个Filter通过执行特定的检查(Header / Body)来反馈某一个控制内容是否通过验证。而且Filter Chain中的每个Filter都是可以被插入的,大家共同实现统一的IFilter接口,因此整个控制层是个可配置、可灵活适应的。 

    (3)不仅仅对于Web的Pre Process,包括多Post Process也都可以采用类似的方式完成。 

    例如:为了避免外部直接访问到具体的URL的Service,可以用Filter完成调用消息的特定路由;假设企业统一的策略是要对所有的Internet传输数据采用基于RC4算法Key SHA1处理的对称保密处理,那么可以对接收的Request通过一个Filter做解密,而在Request数据业务部分完成后,通过另一个Filter对其进行Post Process的加密处理。 

    不过,上面完成的是技术层面的扩展考虑,对于业务本身的易变性还需有必要的扩展准备。例如:一个Web出版物发放系统,其中有个功能叫“给出版物的序言增加出版社的签名”,以此保证用户在网上书店购买的时候可以阅读到正式的序言,而不是被别人篡改过的序言说明。

    以往序言都是通过文本方式保存在Perface的表里面的很多NVarchar字段中,后来有可能被保存在PerfaceOnline表的一个XML数据格式的字段中,但是从贴近业务的技术表述上来看,WSDL关于这个方法其实都是“取得序言数据,并对其编码后的信息由出版社的CA进行签名”。对于建设初期的SOA环境而言,“取得序言数据”这个操作可能在某个Service内部完成。但对于更加集中管理后的企业SOA环境而言,Data Service Provider一般会从具体的服务中抽象出来,也就是从下面的应用数据自治模式转换为集中数据模式。


图:应用数据自治模式

图:集中数据模式

    在集中模式下,可以通过让Service Endpoint“读懂”一些业务化的操作来更加灵活地适应业务要求。为了建立起业务语言和技术处理的关联,这里需要引入表达式解析引擎,并在这个引擎中增加可以解析某些业务化函数的Function Parser。这样,新的执行过程变就为:


图:增加了表达式解析引擎后的执行过程

    具体说明说明:

 (1)通过Express Parser的加入,保证了业务Service可以更为宏观地完成很多业务处理,而更好地隔离了具体业务实现部分。例如:上例可以写成Sign(GetPerfaceData(ID))。这样,即便再次出现数据迁移和数据存储方式的修改,也可以保证Service Endpoint部分的稳定,唯一需要做的就是修改一个Function Parser的函数解析部分。

 (2)每个Function的Parser可以重用。例如:业务上又需要确保序言和封面都是可靠的,那么仅需要组合GetPerfaceData()和GetCoverData()两个Function Parser,新的表达式也就变为Sign(GetPerfaceData() + GetCoverData())就行了。

    总而言之,增加了可以“读懂”业务化语言的Service Endpoint,也就为您的企业SOA后续的发展预留出了更加“聪明”的服务切入点。

    后记 

    文中笔者仅仅根据自身经验,对于企业SOA环境建设中几个技术设计考虑的要点进行了讨论,随着类似工作的继续进行,笔者会将更多的设计要点拿出来与各位架构师探讨。



 
0
相关文章