WSE2.0变化 自适应网络服务时代到来
【IT168 专稿】网络服务架构方兴未艾
许多IT专家相信,2007年及今后几年将成为面向网络服务架构的重要年份。一个显著的标志是,WS-Policy框架将成为SOA旗下认可的标准。来自微软网站的信息表明,随着服务组件架构(Service component architecture,SCA)和服务数据对象(Service Data Object,SDO)这两个规范逐渐成熟,在2007年,两个规范集即将被归为SOA标准。上述情况一方面表明了SOA标准规范集的日益扩大和影响,另一方面可以看出,面向网络服务架构的建设已经成为大势所趋。
其实,早在2004年微软发布WSE(Web Service Enhancements )2.0的时候,就开始了建立新的网络服务架构的准备工作,在2010年代的今后几年里,人类无疑将迎来以服务质量和服务内容为核心的网络服务架构时代,本文将介绍微软在WSE2.0中一个重要的变化,即从 WS-Routing 转移到 WS-Addressing的转变,进而帮助大家能够更清晰地、直观地认识该时代的重要性。
传输中立性(neutrality)
计算机网络发展到今天,在深入讨论 WS-Addressing取代WS-Routing的原因和路由的具体细节之前,理解一个关键的 Web 服务概念是很重要的,这个概念激发了 SOAP 的设计和各种分层 WS-* 规范(包括 WS-Addressing),这个概念就是网络传输的"中立性"。
尽管大多数开发人员认为 Web 服务与 HTTP 具有天生的联系,但基本的体系结构以及更高级的网络分层仍然被设计为是传输中立的。这一点可以在 <soap:Envelope> 元素中看到证据,该元素提供了一个框架,从而将 XML 有效负载从伴随的标头中分离开来,如下例,有效负载和标头之间 SOAP 的差异使我们能够在不创建对传输协议的依赖性的情况下捕获应用程序协议信息。只要发送方和接收方对于放在 SOAP 消息中的 XML 标头的理解是相同的,它们就可以通过各种不同的传输来交换 SOAP 消息。:
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<!-- headers go here 标头-->
</soap:Header>
<soap:Body>
<!-- payload goes here 有效负载-->
</soap:Body>
</soap:Envelope>
尽管传输中立性非常重要,但如果没有传输协议的帮助,大多数现有的 SOAP 结构不可能提供用于引用终结点和调度消息的机制。
最早的满足传输中立性的协议文本WS-Routing
WS-Routing是最早完成此类功能的协议文本,该协议可以使您以传输中立的方式指定消息路由和调度信息。该规范定义了要在 SOAP 标头块中使用的新元素(名为 <r:path>)。这个路径元素有几个子元素,它们可以用来指定路由和调度信息,包括 <r:to> 和 <r:action>。这些元素可以用来捕获与以前相同的信息,但与传输协议没有任何关系,下面的代码框架说明了WS-Routing的基本石用规则:
<s:Envelope
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
>
<s:Header>
<!-- WS-Routing -->
<r:path xmlns:r="http://schemas.xmlsoap.org/rp">
<r:action />
<r:to />
<r:fwd>
<r:via /> *
</r:fwd>
<r:rev>
<r:via /> *
</r:rev>
<r:from />
<r:id />
<r:relatesTo />
<r:fault />
</r:path>
...
其中,<r:fwd>表示消息定义前进路径、<r:rev>表示相应响应消息的相反路径、<r:id> 和 <r:relatesTo>表示消息相互关联的方式。值得说明的是,处理路径信息的路由器必须在将消息发送到路径中下一个节点之前对 WS-Routing 标头进行更改。消息内的路由功能虽然提供了一些有趣的可能性,但也带来一系列安全问题,主要是路由器必须修改标头使得消息签名复杂化,原始的发送方无法签署消息(包括 WS-Routing 标头),而且在不破坏原始签名的情况下通过 WS-Routing 路径发送该消息。
改进后的协议文本WS-Addressing
对WS-Routing改进后的WS-Addressing出现在2004年中叶,新的协议中为Web服务寻址提供了传输中立的机制。WS-Addressing使WS-Routing的简化形式化,并且添加了少量其他功能,下面的表1中列出了这些功能。WS-Addressing 正式放弃了与消息路径相关的 WS-Routing 元素(包括 <r:path>、<r:fwd> 和 <r:rev>),并且假定用户将依靠"下一个跃点"方式来解决路由需要。WS-Addressing 定义的大多数元素在语义上等价于最初在 WS-Routing 中定义的元素。
表1 WS-Addressing主要功能一览表
|
名称 |
WS-Routing 祖先 |
类型 |
说明 |
|
wsa:MessageID |
r:path/r:id |
xsd:anyURI |
用于在时间和空间上唯一标识该消息的 URI。 |
|
wsa:RelatesTo |
r:path/r:relatesTo |
xsd:anyURI |
一对值,说明该消息与另一个消息如何相关。关系类型用 QName 来标识。相关的消息由对应于相关消息 MessageID 值的 URI 来标识。答复消息必须包含 wsa:RelatesTo 标头,该标头由 wsa:Reply 和请求消息的消息 ID 属性组成。 |
|
wsa:To |
r:path/r:to |
xsd:anyURI |
该消息的预期接收方的地址。 |
|
wsa:Action |
r:path/r:action |
xsd:anyURI |
标识符,用于唯一地(和不透明地)标识该消息所暗示的语义。 |
|
wsa:From |
r:path/r:from |
endpoint-ref |
对作为消息来源的终结点的引用。 |
|
wsa:ReplyTo |
N/A |
endpoint-ref |
终结点引用,标识答复该消息的预期接收方。如果期望得到答复,则消息必须包含 wsa:ReplyTo 标头。发送方必须使用 wsa:ReplyTo 标头的内容来表示答复消息。如果没有 wsa:ReplyTo 标头,则可能使用 wsa:From 标头的内容来编制到来源的消息。如果消息无有意义的答复,则可能不存在该属性。如果有该属性,则 wsa:MessageID 标头是 REQUIRED。 |
|
wsa:FaultTo |
N/A |
endpoint-ref |
终结点引用,用于标识接收与该消息相关的错误的预期接收方。表示错误消息时,发送方必须使用该引用的内容来表示错误消息。如果没有该引用,发送方可能使用 wsa:ReplyTo 的内容来表示错误消息。如果该引用和 wsa:ReplyTo 都不存在,则发送方可能使用 wsa:From 的内容来表示错误消息。如果有该属性,则 [message id] 属性是 REQUIRED。 |
其中,<wsa:To>用来指定消息的目标,<wsa:Action>用来定义操作,<wsa:MessageID>用来为消息指定唯一的ID。在答复消息时,使用<wsa:RelatesTo>标头和它的RelationshipType属性表示答复消息与请求消息之间的关系。WS-Addressing中,请求消息时只有<wsa:To>和<wsa:Action>是必需的(其他元素是可选的),支持WS-Addressing的SOAP基础结构应当基于这两个值来调度消息。在中间路由节点,可以将<wsa:To>视为逻辑地址,并提供到物理地址的简单转换。
在 WS-Routing 中,<r:from> 只是 URI。在 WS-Addressing 中,<wsa:From> 元素的类型是终结点引用。终结点引用使得将其他终结点元数据与地址一起传递成为可能。理想情况下,终结点引用将包含足够的信息,以便客户能够自动协商交互方式。为了完成这个操作,终结点引用必须将地址与用来发现合约详细信息和策略的其他属性包含在一起。这些其他属性可能包括服务名称、端口名称、端口类型以及用来描述服务的要求、功能和首选项的 WS-Policy 语句。引用还应当能够包含所需数量的应用程序特有的属性。
WSE2.0立足网络服务宗旨,支持WS-Addressing
微软在开发网络服务增强服务WSE 2.0 中的一个最基本的更改是放弃了对 WS-Routing 的支持,并添加了对 WS-Addressing 的支持。WSE 2.0 在 Microsoft.Web.Services.Addressing 命名空间中为 WS-Addressing 提供了多个新类。整个消息 API 已经重新设计为围绕终结点引用,而不是 URI。WSE 2.0 引入了一个名为 EndpointReference 的新类,这个类在整个 WSE 2.0 API 中替换了 System.Uri。例如,SoapSender 和 SoapReceiver 类现在直接处理 EndpointReference 对象。下面的代码片段模拟了在一个基于 TCP 的简单聊天应用程序中如何利用 SoapSender 类来使用 EndpointReference 对象:
...
SoapEnvelope env = new SoapEnvelope();
env.Context.Addressing.Action = String.Format("urn:chat:message");
EndpointReference epr =
new EndpointReference("soap.tcp://askonnard:123/aaron"));
env.Context.Addressing.ReplyTo = new ReplyTo(epr);
env.CreateBody(); // must create body before setting it
env.Body.InnerXml = String.Format(
"<x:message xmlns:x=''urn:chat''><user>{0}</user><msg>{1}</msg>
</x:message>", user, msg);
...
EndpointReference epr = new EndpointReference(
new Uri("soap.tcp://askonnard:456/monica"));
SoapSender ss = new SoapSender(epr);
ss.Send(env);
...
一旦使用 WSE 2.0 发送消息,WSE 2.0 就会自动添加必需的 WS-Addressing 消息信息标头。
WSE 2.0倚仗WS-Addressing保护路由的安全
由于WSE 2.0全面支持WS-Addressing,则可以安全地签署和加密 SOAP 消息,而不用面对前面讲述WS-Routing时的问题。安全的基础在于WS-Addressing 标头是不可变的,中间节点无法修改它们,因此可以签署和加密消息(包括 WS-Addressing 标头)以达到用户需要的、合适的安全级别。
下面的示例演示了如何使用 WSE 2.0 代理类签署整个 SOAP 消息:
...
MyClaimsService e = new MyClaimsService();
e.RequestSoapContext.Security.Tokens.Add(GetSecurityToken());
e.RequestSoapContext.Security.Elements.Add(
new Signature(tok));
e.Submit(claim);
...
该代码产生签名的消息,不存在安全问题,建议在建立网络系统时签署或加密WS-Addressing 标头,以提升系统的安全性。
结论
通过比较WS-Routing和WS-Addressing两个分别出现在WSE1.0和WSE2.0中的WS-*类协议标准,可以看出网络服务框架中那些成员协议的沿革动力来自于第一线的市场与用户对于网络服务功能的强烈要求,任何一个IT巨头,包括微软公司为代表的那些行业垄断者们,如果不考虑来自市场的包括开源、服务性能等等来自市场前沿和用户的这些基本需求,那么等待他们的将是灭顶之灾,而不会是滚滚财源!