antony--异域空间
性格左右命运,气度影响格局!

http://extjsextendercontrol.codeplex.com/SourceControl/ListDownloadableCommits.aspx

http://www.yaosansi.com/post/551.html

http://blog.csdn.net/jim_yeejee/

http://www.infoq.com/cn/interviews/fengdahui-database-architecture

http://www.dbanotes.net/

翻译:张勇,周竞


http://dev.csdn.net/develop/article/43/43345.shtm   
http://dev.csdn.net/develop/article/54/54503.shtm

http://topic.csdn.net/t/20041208/10/3625223.html


摘要:
如何使用支持WS安全规范的WSE(Microsoft Web Services Enhancements)使加密SOAP能够跨越标准HTTP呢?讲述了SOAP报文加密是如何进行,在WS安全和XML加密规范中又是如何定义的。
目录:
? 介绍WSE
? WSE的安全特性
? 加密SOAP报文
? WSE对加密的支持
? 配置WSE
? SOAP报文的对称加密算法
? 使用X.509证书来加密SOAP报文
? 选择报文的节点(组成部分)来加密
? 局限性和协作性细节
? 结论
WSE介绍
为了使Web 服务在企业内部运行得更好,新一代的Web 服务规范被提出来.建议应该改善对Web 服务很重要的方面如 安全,可靠报文,发送附件对地区间的协调性.为了支持这些提议的标准,ms发布了WSE1.0 sp1,它包含了一系列的类来支持这些新的协议,如基于Microsoft的asp.net宿主的过滤器,拦截进入和发出的SOAP报文,拦截或者产生SOAP头来支持需求的功能.WSE支持以下的规范:
? WS-安全和Web 服务安全补遗
? WS附件
? WS路由
? WS引用
WSE的安全特性
在WSE运行时,由一系列过滤器产生和读取WS-security兼容的SOAP报头.当在一台支持WSE的Web服务器上接收到SOAP报文时,SOAP报文经过一系列输入过滤器读取WS-*兼容的报头,如有必要修改它们,产生一系列相关程序对象.同样,输出的报文是经过一些列输出过滤器,序列化一定的报头如WSE对象定义的. 所有被WSE1.0 sp1所支持的Web服务安全特征由安全输入和输出过滤器通过SecurityInputFilter和SecurityOutputFilte对象来实现.它包含:数字签名,加密,签署和加密用户标识,签署和加密用x.509证书, 签署和加密用自定义2进制标识.
加密SOAP报文
用统一的格式来传输数据,使得有价值的数据容易被恶意用户访问,以至被拦截.使用SOAP和xml来传输数据不但数据有潜在的安全威胁,而且你Web 服务的内在工作方式有可能被发现,通过观察SOAP 报文本身带的 xml 语法.使用合适的加密算法,数据和信息接口可以得到完全的保护.加密是简单的使用一种可逆的算法使用特定的密钥对明文进行加密,使得数据如果不解密则无法阅读. 如今,互联网加密的最常见的形式引入了一种传输级的加密模式,例如IPSEC和SSL,在传输层加密 .有了一定的安全性,但是传输层加密影响性能,尤其是当只有SOAP报文的一部分需要加密时.而且传输层加密不允许报文安全的路由通过Web 服务作为中介.因为报文需要解密由媒介在她能以新的加密的流传送到最终接收者之前,
Xml加密是如何工作的
Xml加密协议指定了SOAP报文的部分或者全部可以被加密.当使用xml加密时,将针对xml文档的部分进行加密,加密后的内容在EncryptedData节点内部.WS安全是基于 xml加密的,充分保证了使用xml加密来加密SOAP 报文时, EncryptedData 是security头部节点元素的引用.如果在SOAP报文的主体中有多个节点被加密时,每个节点参考自每个独立的且在ReferenceList 中的ReferenceData节点
对于一个EncryptedData 节点,一些密钥的信息可以在KeyInfo节点指定,加密的算法则在EncryptionMethod节点中指定,keyinfo节点按照xml签名规范来定义的.
一个加密后的SOAP 报文
下面的SOAP报文示例有一个payment节点,含有一些敏感的客户信息.

引用

<SOAP:Envelope SOAP:xmlsn="http://www.w3.org/2002/12/SOAP-envelope">
<SOAP:Header>
...
</SOAP:Header>
<SOAP:Body>
...
<x:Order Type="Purchase" x:xmlns="http://example.com/order">
<x:Payment Type="CreditCard">
<x:CreditCard Type="Visa">
<x:CardNumber>123456789123456</CardNumber>
<x:ExperationDate>1108</ExperationDate>
</x:CreditCard>
</x:Payment>
...
</x:Order>
...
</SOAP:Body>
</SOAP:Envelope>



因为payment节点含有敏感的数据,所以它应该被加密.下面的例子显示了相同的信息,但是payment节点被EncryptedData节点代替了.EncryptedData节点内含有对payment 节点内部内容加密后的密文. EncryptedData节点是参考自security头中的DataReference 节点的

引用

<SOAP:Envelope SOAP:xmlsn="http://www.w3.org/2002/12/SOAP-envelope"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
xmlns:xsig="http://www.w3.org/2000/09/xmldsig#"
xmlns:WSse="http://schemas.xmlSOAP.org/WS/2002/04/secext">
<SOAP:Header>
<WSse:Security>
<xenc:ReferenceList>
<xenc:DataReference URI="#OrderID"/>
</xenc:ReferenceList>
</WSse:Security> ...
</SOAP:Header>
<SOAP:Body>
...
<x:Order Type="Purchase" x:xmlns="http://example.com/order">
<xenc:EncryptedData Id="OrderId">
<xenc:EncryptionMethod
Algorithm= "http://www.w3.org/2001/04/xmlenc#tripledes-cbc"
<xsig:KeyInfo>
<xsig:KeyName>My Symmetric Key</xsig:KeyName>
</xsig:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>...</CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
...
</x:Order>
...
</SOAP:Body>
</SOAP:Envelope>




当然,在这个例子中,你可以用数字签名来签署该报文,来防止怀有恶意的人来窜改数据,或者用时间戳或者其他唯一的标识来判断信息是否受到攻击.
加密的种类
对称加密和不对成加密
加密得算法可以分为对称加密和不对称加密.在对称加密算法中,一个密钥被用来进行信息交换得两方共享.发送方利用私钥得拷贝来加密数据.在接收方,利用同样得私钥的拷贝来解密数据.绝大多数得加密,如基于共享密码和共享安全标识都是对成加密得例子.
在这种类型的系统中,一个中心的服务器分发共享的密钥给需要安全交互的使用者.对称加密的缺点是共享密钥的管理,分发和保护它们的安全性,特别是在象internet这样的公网上.
为了克服在公共网络中管理密钥的的难度,使用成对的密钥来取代单一的密钥.在不对成加密算法中,双方都互相拥有一个私钥和一个密钥.
公钥是利用一种不可逆的方法对私钥进行操作后产生的,因此一旦两者中的一种用来加密数据,另外一种就可以用来解密.另外,不可由公钥来推测出私钥,而且只有用私钥来解密用公钥加密的数据.当发送异步加密的报文时,发送者利用接收者的公钥加密报文,确保只有接收者可以利用他的私钥来解密报文.如果你用另外一种方式来处理,任何人都可利用可利用的公钥来解密报文.不对称加密是PKI的基础,pki是x.509安全标准的基础.不对成加密算法是一种典型基于对大数处理的算法,如指数合对数运算.它比对成加密算法需要更多的cpu时间来进行加密和解密.,因为这个原因,不对成加密经常用来安全的传送一个对称的”会话”密钥,用来加密交互的剩余部分,这也只是在信息交换的持续周期内有效.
因为公钥可以很容易的获得,使用公钥进行加密减轻了分发和管理密钥的难度.不幸的是,这种方便性的代价是不对成加密算法通常比对成加密算法慢几个数量级.由于此,不对称加密方法只用来处理比较小的数据.例如安全密钥和标识以及数字签名.
WSE对加密的支持
WSE支持对SOAP 报文的部分加密.对称加密使用一个共享的密钥,不对称加密支持使用x.509证书.当使用WSE来加密SOAP报文时,整个body节点的内容被加密,除非明确指定不要加密.下面举了2个例子,一个加密这个主体部分,一个加密部分.
WSE运行时库实现了所有的WS-security.在SecurityInputFilter 和SecurityOutputFilter 类中SecurityOutputFilter 类中.前者通过查找Security节点在一个
进入的SOAP报文中,如果该节点存在.它创建了一个代表任意安全标记和加密密钥,解密节点,验证任何数字签名的对象.对于一个进入的报文,任何任何安全的节点都剋通过报文产生的SOAPcontext对象的安全属性进行访问.相反的, SecurityOutputFilter为进出报文实施加密和签名的操作,附带任何特定的安全标记或者加密密钥.安全措施,比如添加标记,加密,或者签署进出报文利用报文的SOAPContext.Security和SOAPContext.ExtendedSecurity属性, ExtendedSecurity只在需要创建安全报头时候使用Security属性只在为包含最终目的地时使用
配置WSE
尽管在安装时,WSE已经被安装到asp.net Web 服务器上,但是还需要一些额外的配置,如果需要那些asp.net应用使用安全支持的话.当创建完毕asp.net Web 服务后工程后,visual studio.net,引用Microsoft.Web.Services.dll 程序集需要加载到该项目中.你也需要对SOAPExtensionTypes节点添加一个新的SOAP扩展.这可在 Web.config文件中创建一个新的 add 节点.如下所示

引用

<configuration>
<system.Web>
...
<WebServices>
<SOAPExtensionTypes>
<add type=
"Microsoft.Web.Services.WebServicesExtension,
Microsoft.Web.Services,
Version=1.0.0.0,
Culture=neutral,
PublicKeyToken=31bf3856ad364e35"
priority="1" group="0" />
</SOAPExtensionTypes>
</WebServices>
</system.Web>
</configuration>



type属性的值必须不能包含任何间断或者额外的空格.这个例子为了可读性有额外的换行. 如果WebServices 和SOAPExtensionTypes 节点不存在,它们必须加到 Web.config文件里面.一种更容易的方法是完全WSE配置工具.一种visual studio的插件,使用它您可以非常容易的配置使用WSE的Web service 项目.当然还有一下其他相关的配置必须手工配置.
当使用WSE进行编程时,你需要添加一个Microsoft.Web.Services 和一个System.security名字空间的引用.在客户端和服务器端的工程中,如果既在客户请求和服务器回应中加密了.在客户部分你应该使用添加Web引用工具为基于WSE的Web service工程产生Web service代理.
给SOAP报文进行对称加密
接下来,让我们再来看看如何用WSE来给SOAP报文使用对称密钥加密。下面的例子是基于一个启用WSE的Web服务的,这个Web服务将返回一个SOAP回应报文,在该报文正文内包含了一些敏感数据。这么说,客户端给服务发送一个简单的Web服务请求,该请求将返回一个由三元 DES对称加密算法(使用了一个共享密钥和一个初始向量,IV)加密过的XML文档,当客户端收到了加密后的回应信息后,SecurityInputFilter将调用一个在客户端的解密密钥提供程序,来访问客户端上相同的共享密钥,以此来对报文体进行解密,这个解密密钥提供程序必须由你来编写,并且提供一个用于同步共享密钥的方法。这些例子假设双方都知道密钥,并且我们所要做的,仅仅是提供密钥的名字,以此作为一个暗示,给对方知道我们用的是哪个密钥加密的信息。
双方之间管理、同步和和对密钥保密的时候一定要多加小心。有个解决方案使用了一个分布式密钥机制,例如Kerberos。但从WSE的1.0版本开始,WSE就不再继续支持Kerberos了。
加密对外发送的报文
这里我简单描述下如何创建一个可以返回个被加密的XML文档的Web服务。第一步先用using指示符来添加必要的命名空间,如下:

引用
using System.Web.Services;
using Microsoft.Web.Services;
using Microsoft.Web.Services.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;



GetXmlDocument方法使用了的.NET框架实现的三元DES算法,采用128位密钥和64位初始化向量(IV),能够生成对称密钥。这个密钥还将拥有一个名字,并被添加到应答报文的SoapContext元素上,之后被SecurityOutputFilter使用于加密简单的XML文档,这个方法最后将返回给客户端。更多关于.NET框架的加密技术,请看.NET框架开发者指南上的Cryptography Overview一文。

引用

//返回由三元DES对称算法加密后的数据
[WebMethod (Description="返回一个由对称加密算法机密后的敏感XML文档", EnableSession=false)]

public XmlDocument GetXmlDocument()
{
//创建一个用于返回的简单的XML文档
XmlDocument myDoc = new XmlDocument();
myDoc.InnerXml =
"<EncryptedResponse>这里是敏感数据.</EncryptedResponse>";

//得到对外发送的回应报文的SoapContext
SoapContext myContext = HttpSoapContext.ResponseContext;

//创建一个用于加密的对称密钥,由于密钥是对称的,这些相同的数据必须存在有需求的客户端上。

//定义共享的16字节数组,用来表示128位密钥
byte[] keyBytes = {48, 218, 89, 25, 222, 209, 227, 51, 50, 168, 146,
188, 250, 166, 5, 206};

//定义共享的8字节(64位)数组,也就是初始化向量(IV)
byte[] ivBytes = {16, 143, 111, 77, 233, 137, 12, 72};

//创建三元DES算法的新实例
SymmetricAlgorithm mySymAlg = new TripleDESCryptoServiceProvider();

//设置好密钥和IV
mySymAlg.Key = keyBytes;
mySymAlg.IV = ivBytes;


//创建一个新的WSE对称加密密钥
EncryptionKey myKey = new SymmetricEncryptionKey(mySymAlg);


//给他取个名字?
KeyInfoName myKeyName = new KeyInfoName();
myKeyName.Value = "http://example.com/symmetrictestkey";
myKey.KeyInfo.AddClause(myKeyName);


//使用对称密钥来创建一个新的EncryptedData元素
EncryptedData myEncData = new EncryptedData(myKey);


//将EncryptedData元素添加到SOAP回应上,告诉过滤器用指定的密钥来加密信息正文

myContext.Security.Elements.Add(myEncData);

return myDoc;
}



基于前面的方法,WSE管道产生了下面有相应的安全头信息,密文和密钥信息的回应报文:

引用

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<wsu:Timestamp
xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
<wsu:Created>2003-02-11T02:07:23Z</wsu:Created>
<wsu:Expires>2003-02-11T02:12:23Z</wsu:Expires>
</wsu:Timestamp>
<wsse:Security soap:mustUnderstand="1"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/secext">
<xenc:ReferenceList
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:DataReference URI=
"#EncryptedContent-f50076e3-5aea-435e-8493-5d7860191411" />
</xenc:ReferenceList>
</wsse:Security>
</soap:Header>
<soap:Body xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"
wsu:Id="Id-d2f22e02-a052-4dcb-8fbc-8591a45b8a9f">
<xenc:EncryptedData
Id="EncryptedContent-f50076e3-5aea-435e-8493-5d7860191411"
Type="http://www.w3.org/2001/04/xmlenc#Content"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyName>http://example.com/symmetrictestkey</KeyName>
</KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>0T5ThoGg14JmElph...qDJS=</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soap:Body>
</soap:Envelope>




注意,在报文正文中ReferenceList元素包含了一个到EncryptedData元素的引用,这个元素包含了密钥的名字,使用的加密算法和一个数据的密文形式。
解密收到的报文
不管是在客户端还是在服务器端,WSE总是在SecurityInputFilter实现报文解密的,由于对称加密需要由公共密钥派生出来的加密密钥,你需要创建一个SecurityInputFilter能够调用的方法来得到这个对称密钥,然后你就能使用包含在EncryptedData中的密钥和算法信息来帮你找到正确的共享密钥和加密算法了。这个方法必须实现在从Microsoft.Web.Services.Security.IDecryptionKeyProvider派生出来的类中。在我的例子中,DecryptionKeyProvider.GetDecryptionKey方法返回了对称密钥,如下:

引用


public DecryptionKey GetDecryptionKey(string encAlgorithmUri,
KeyInfo keyInfo)
{

//重新创造同样的用于表示128位密钥的16个字节
byte[] keyBytes = {48, 218, 89, 25, 222, 209, 227, 51, 50, 168, 146,
188, 250, 166, 5, 206};


//重新创造表示初始化向量的8个字节(64位)
byte[] ivBytes = {16, 143, 111, 77, 233, 137, 12, 72};

SymmetricAlgorithm mySymAlg = new TripleDESCryptoServiceProvider();
mySymAlg.Key = keyBytes;
mySymAlg.IV = ivBytes;

//重新创建对称加密密钥
DecryptionKey myKey = new SymmetricDecryptionKey(mySymAlg);

return myKey;
}



即便在我的方法中并没使用他们,WSE还是要把KeyInfo元素和加密算法的URI传递给这个方法的,决定使用哪一个共享密钥或者加密算法来产生对称密钥

为了让SecurityInputFilter能够访问到GetDecryptionKey方法,下面的配置信息必须加入到应用程序的配置文件中(也就是 app.config 文件)

引用


<configuration>
...
<microsoft.web.services>
<security>
<decryptionKeyProvider
type="MyClient Assembly.DecryptionKeyProvider,
MyClientAssembly" />
</security>



type 属性不能有任何过多的空格或者任何换行。他们只包含上面的内容以增强可读性,这个也可一用WSE设置工具来修改。一旦DecryptionKeyProvider类被添加到客户端而且WSE安全支持已经配置好了,WSE将自动拦截加密数据,一个基于标准的Web服务的2次开发平台程序,就可以让你随心所欲的给客户端编程了。

使用 X.509 证书来给SOAP报文加密
正如我前面提到的,非对称操作有一定开销。当传输大量数据时,从性能上来说,用非对称算法来加密这些数据会显得不太实际,WSE就这个问题,实现了一种伪非对称性加密(pseudo-asymmetric encryption)。和非对称性加密的报文相比,WSE使用一个非对称性算法和X.509证书的一个公开备份,以此来加密对称密钥,而实际上这些被用来给报文加密。当收到报文后,SecurityInputFilter得到和X.509证书相关联的私有密钥,以此给对称密钥解密,然后用解密后的密钥给报文正文解密。为了能让这个例子能够正常工作,一个来自受信任的证书认证的X.509证书(支持加密),必须出现在客户机器上当前用户帐号的个人证书储藏室里面,这个证书的私有密钥也必须出现在本地机器在主管Web服务的服务器的帐号里。另外,CA证书链中的一个证书必须出现在客户端的受信任储存室里,那样WSE才知道可以信任接受到的X.509证书。
加密对外发送的报文
我已经修改了前面的GetXmlDocument方法,让它可以使用由WSE实现的基于X.509非对称加密技术。加密回应报文,FindCertificateBySubjectString方法可以用来接收客户端证书的公开备份,一个来自本地机器账号的个人储存室给的客户端证书。这个证书然后被用来创建一个新的 X.509安全Token,这个Token将被加入到响应报文的SoapContext的安全Token集合里。另外,在对称加密例子中引用的命名空间,你应该再加一个using指示附来引用一个Microsoft.WebServices.Security.X509命名空间。GetXmlDocument方法代码如下:

引用
//创建一个用于返回的简单XML文档
XmlDocument myDoc = new XmlDocument();
myDoc.InnerXml =
"<EncryptedResponse>This is sensitive data.</EncryptedResponse>";
"<EncryptedResponse>这里是敏感数据.</EncryptedResponse>";

//得到响应报文的SoapContext
SoapContext myContext = HttpSoapContext.ResponseContext;

//打开并读取本地机器帐号的个人证书储存室
X509CertificateStore myStore =
X509CertificateStore.LocalMachineStore(
X509CertificateStore.MyStore);
myStore.OpenRead();

//查找所有名为”我的证书”的证书,然后将所有匹配的证书添加到证书集合中
X509CertificateCollection myCerts =
myStore.FindCertificateBySubjectString("My Certificate");
X509Certificate myCert = null;

//查找在集合中中的第一个证书
if (myCerts.Count > 0)
{
myCert = myCerts[0];
}

//确定我们有一个可以用于加密的证书
if (myCert == null || !myCert.SupportsDataEncryption)
{
throw new ApplicationException("Service is not able to
encrypt the response");

return null;
}
else
{
//使用有效的证书来创建一个安全Token
X509SecurityToken myToken = new X509SecurityToken(myCert);
//WSE将使用这个标记来加密报文正文的
//WSE产生一个KeyInfo元素,用来请求客户端上曾用于给报文解密的证书

EncryptedData myEncData = new EncryptedData(myToken);
//将已加密数据元素添加到响应报文的SoapContext上
myContext.Security.Elements.Add(myEncData);

return myDoc;
}



基于前面的方法,WSE管道产生了下面的有相应Security头、密文和密钥信息的元素:

引用

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<wsu:Timestamp
xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
<wsu:Created>2003-02-11T01:34:01Z</wsu:Created>
<wsu:Expires>2003-02-11T01:39:01Z</wsu:Expires>
</wsu:Timestamp>
<wsse:Security soap:mustUnderstand="1"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/secext">
<xenc:EncryptedKey
Type="http://www.w3.org/2001/04/xmlenc#EncryptedKey"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier ValueType="wsse:X509v3">
YmlKVwXYD8vuGuYliuIYdEAQQPw=
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>UJ64Addf3Fd59XsaQ=…</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI=
"#EncryptedContent-608eef8b-4104-4469-95b6-7cb4703cfa03" />
</xenc:ReferenceList>
</xenc:EncryptedKey>
</wsse:Security>
</soap:Header>
<soap:Body xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"
wsu:Id="Id-70179c5b-4975-4932-9ecd-a58feb34b0d3">
<xenc:EncryptedData
Id="EncryptedContent-608eef8b-4104-4469-95b6-7cb4703cfa03"
Type="http://www.w3.org/2001/04/xmlenc#Content"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
<xenc:CipherData>
<xenc:CipherValue>
4o1b4befwBJu6tzuaygfrAaX0UGtaYKcw2klIbuZPjLi...z8i2ypHN4+w==
</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soap:Body>
</soap:Envelope>



注意在这个已加密的报文里面,由非对称加密过的EncryptedKey元素包含了用于给报文正文加密的对称加密密钥。ReferenceList元素引用了报文正文的EncryptedData元素的Id属性。虽然我在我的例子中没这样做,标记这个消息以便能让容器验证发送者其实是个不错的想法。关于使用WSE来标记报文的详细信息,看WS-Security Authentication and Digital Signatures with Web Services Enhancements
给收到的报文解密
当收到一个由X.509证书加密后的报文后,SoapInputFilter会自动尝试使用用户密钥储存室的私有密钥来进行解密,当然,这个需要告诉WSE运行时哪里可以找到这个证书的额外配置信息。这个信息由应用程序配置文件的Security元素所指定,这个例子在客户端上的应用程序配置文件是App.config。对于 X.509加密,你只需要添加一个x509子节点,内容和下面一样就可以了

引用

<x509
storeLocation="CurrentUser"
verifyTrust="true"
allowTestRoot="false" />




在我的例子中,我将x509节点的storeLocation属性设为CurrentUser,假设证书在当前用户的证书储存室里,当我使用了来自CA的受信任证书之后,我也将verifyTrust设为true了。这些属性还能够用WSE的设置工具来修改。利用这些信息,WSE能够得到报文中证书的私有密钥,还能用这个来给对称性会话密钥解密,解密后的内容到头来还要给报文正文解密。
选择用于解密的报文元素
当整个消息正文由默认设置给加密后,WSE能被用来给SOAP报文内的特定元素加密;唯一的问题是,在Security头元素那的元素不能被加密。你还可以加密嵌套的元素,
在这个例子服务中,我修改了GetXmlDocument方法用的X.509版本,用一个基于X.509的安全Token来同时给EncryptedSubResponse和它的EncryptedResponse父节点进行数字化加密,返回的XML文档如下:

引用
<Response>
<NotEncrypted>
回应报文的这里没有必要被加密
</NotEncrypted>
<EncryptedResponse>
<EncryptedSubResponse>
这里是敏感数据.
</EncryptedSubResponse>
</EncryptedResponse>
</Response>



为了加密一个元素,它需要一个wsu:Id属性,以便当XML被序列化后引用可以加到该节点上了。命名空间wsu被定义为:

引用
xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility



为了完成这个,我将这个XML加到一个新的XML文档,然后通过.NET框架支持的Microsoft XML文档对象模型(DOM)给它添加一个Id属性,此外还需要将配件System.Xml加入到工程引用里面,加上下面的话:

引用

using System.Xml;
using System.Xml.Serialization;



当我将多个Id属性加到嵌套的元素上后,我由EncryptedSubResponse元素开始依次遍历到它的父节点EncryptedResponse,如下:

引用

string [] myId = {"Id:" + Guid.NewGuid(),"Id:" + Guid.NewGuid()};


//创建一个用于返回XML的XML文档
XmlDocument myDoc = new XmlDocument();
myDoc.LoadXml("<Response>" +
"<NotEncrypted>回应报文的这里没有必要加密" +
"</NotEncrypted>" +
"<EncryptedResponse>" +
"<EncryptedSubResponse>" +
"这里是敏感数据. " +
"</EncryptedSubResponse>" +
"</EncryptedResponse>" +
"</Response>");

//得到EncryptedSubResponse节点
XmlNode = myDoc.FirstChild.LastChild.FirstChild;


//向上遍历元素,添加两个Id属性
//向上保证内部的多数元素可以优先被加密
//否则我们会得到一个异常
for (int i=0;i<myId.Length;i++)
{

//创建新的Id属性
string wsu = "http://schemas.xmlsoap.org/ws/2002/07/utility";
XmlNode myAttr = myDoc.CreateNode(XmlNodeType.Attribute, "wsu",
"Id", wsu);
myAttr.Value = myId[ i ];

//将属性添加到文档
root.Attributes.SetNamedItem(myAttr);
root = root.ParentNode; // 移动到父节点
}



假设我早就用我前面的逻辑得到了来自X.509证书的安全记号,我将这些引用添加到EncryptedData元素,如下:

引用

//循环遍历Id值,将其添加到新的EncryptedData元素上
for (int i=0;i<myId.Length;i++)
{
//创建一个新的头,”#”是的前缀,用来保证相关的URI能够引用到头
EncryptedData myEncHeader = new EncryptedData(myToken, "#"+myId[ i ]);
//添加一个新的头到集合中
myContext.Security.Elements.Add(myEncHeader);
}
//返回加密数据
return myDoc;



下面是被WSE在运行时序列化后产生的报文加密后的结果

引用

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<wsu:Timestamp
xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
<wsu:Created>2003-02-11T20:21:52Z</wsu:Created>
<wsu:Expires>2003-02-11T20:26:52Z</wsu:Expires>
</wsu:Timestamp>
<wsse:Security soap:mustUnderstand="1"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/secext">
<xenc:EncryptedKey
Type="http://www.w3.org/2001/04/xmlenc#EncryptedKey"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier ValueType="wsse:X509v3">
YmlKVwXYD8vuGuYliuIOXOY7ZYN9PwHbfAhCiYOV0aYdEAQQPw=
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>
UyKGBEXdY8lYSzqgdgxOXOY7ZYN9PwHbfAhCiYOV0...bwRnWk=
</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI=
"#EncryptedContent-cf014249-0e2a-4f8b-9002-13a7de916be0" />
</xenc:ReferenceList>
</xenc:EncryptedKey>
<xenc:EncryptedKey
Type="http://www.w3.org/2001/04/xmlenc#EncryptedKey"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier ValueType="wsse:X509v3">
YmlKVwXYD8vuGuYliuIYdEAQQPw=
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>
In8Kf1cIdiJJJXCLZ+... wMqBEevXmzk=
</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI=
"#EncryptedContent-0744279a-02bf-4ad1-998e-622208eded0e" />
</xenc:ReferenceList>
</xenc:EncryptedKey>
</wsse:Security>
</soap:Header>
<soap:Body>
<GetXmlDocumentResponse xmlns="http://example.com/dime/">
<GetXmlDocumentResult>
<Response>
<NotEncrypted>
This part of the response does not need encryption
</NotEncrypted>
<EncryptedResponse
wsu:Id="Id:e5e8d792-abe7-4476-91d0-856fbdf4a958"
xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
<xenc:EncryptedData
Id=
"EncryptedContent-cf014249-0e2a-4f8b-9002-13a7de916be0"
Type="http://www.w3.org/2001/04/xmlenc#Content"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod
Algorithm=
"http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
<xenc:CipherData>
<xenc:CipherValue>
2MNHCkGVH/5jb0pF4pCh3u2VaUKsWSA...AfEvJZT=
</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</EncryptedResponse>
</Response>
</GetXmlDocumentResult>
</GetXmlDocumentResponse>
</soap:Body>
</soap:Envelope>



注意,在这个加密后的报文里,这里有一个用于表示X.509证书的BinarySecurityToken元素,但有两个分开的EncryptedKey元素,每个EncryptedData元素都被添加到SoapContext,在最外面的被加密的元素中(EncryptedResponse),你只能看到EncryptedData元素,当EncryptedResponse被加密后,表示EncryptedSub元素的EncryptedData元素也随之转换为密文了。当这个报文在客户端被收到时,SecurityInputFilter使用来自记号的信息来得到曾给两个EncryptedKey元素解密过的私有密钥。

 

 

 

http://msdn.microsoft.com/zh-cn/library/aa302390.aspx

 

Web 服务安全性

发布日期 : 10/8/2004 | 更新日期 : 10/8/2004

浏览全部的安全性指导主题

Microsoft Corporation

本章内容

灵活开放标准的使用使得 Web 服务成为一种优秀的机制,可以通过 Web 服务将功能向客户端公开,以及用它来承载前端 Web 服务可以访问的中间层业务逻辑。然而,由于标准的局限性,以及需要支持各种客户端类型,从而使 Web 服务面临着安全方面的挑战。

本章介绍如何开发和应用身份验证、授权和安全通信技术来保护 ASP.NET Web 服务。本章首先简要介绍三种主要的 Web 服务安全模型–传输/平台、应用程序和消息级–,然后详细介绍实现适用于 ASP.NET Web 服务的可用选项及传输/平台级安全性。

目标

利用本章来:

  • 保护您的 Web 服务。

  • 实现平台/传输级安全性解决方案。

  • 比较和对比平台/传输级安全性与消息级安全性。

  • 标识和使用由 ASP.NET Web 服务提供的网关守卫。

  • 将客户端凭证传递给需要身份验证的 Web 服务。

  • 将原调用者标识从 Web 服务传递到下游系统。

  • 设计适合于您的 Web 服务的身份验证、授权和安全通信解决方案。

适用于:

本模拟适用于以下产品和技术:

  • Microsoft® Windows® Server 2000 和 Windows Server™ 2003 操作系统

  • Microsoft Internet Information Services (IIS) 5.0 及更高版本

  • Microsoft Active Directory® 目录服务

  • Microsoft .NET Framework 1.0 版(带 service pack 2)及更高版本

  • Microsoft Visual C#® .NET 开发工具

如何使用本章

要想从本单元获得最大价值,您应该:

本页内容

Web 服务安全性模型 Web 服务安全性模型
平台/传输安全性体系结构 平台/传输安全性体系结构
身份验证和授权策略 身份验证和授权策略
配置安全性 配置安全性
将身份验证的凭证传递给 Web 服务 将身份验证的凭证传递给 Web 服务
传送原调用者 传送原调用者
受信任的子系统 受信任的子系统
访问系统资源 访问系统资源
访问网络资源 访问网络资源
访问 COM 对象 访问 COM 对象
将客户端证书用于 Web 服务 将客户端证书用于 Web 服务
安全通信 安全通信
小结 小结

Web 服务安全性模型

可以在三个级别应用 Web 服务安全性:

  • 平台/传输级(点对点)安全性

  • 应用程序级(自定义)安全性

  • 消息级(端对端)安全性

每一种方法都具有各自的优缺点,下面将详细阐述这些方法。选择哪一种方法在很大程度上取决于消息交换中涉及到的体系结构和平台的特点。

本章着重介绍平台级和应用程序级的安全性。消息级安全性将在全局 XML Web 服务体系结构 (GXA) 提案中以及专门在 WS-Security 规范中进行介绍。在编写本指南时,Microsoft 刚刚发布了 Web 服务开发工具包的技术预览版本。它可用于开发符合 WS-Security 规范的消息级安全性解决方案。有关详细信息,请参阅 http://msdn.microsoft.com/webservices/building/wse/

平台/传输级(点对点)安全性

两个终结点(Web 服务客户端和 Web 服务)之间的传输通道可用于提供点对点的安全性。 1 阐释了这种情况。

f10sn01

1. 平台/传输级安全性

当您使用平台级安全性时(它假定在公司 Intranet 上安装了紧密集成的 Microsoft_ Windows_ 操作系统环境):

  • Web 服务器 (IIS) 提供基本、摘集成和证书身份验证。

  • ASP.NET Web 服务继承了某些 ASP.NET 身份验证和授权功能。

  • 可以使用 SSL 和/或IPSec 提供消息完整性和机密性。

何时使用

传输级安全性模型简单明了,并且可用于许多(主要是基于 Intranet 的)方案;在这些方案中,可以严格控制传输机制和终结点配置。

传输级安全性的主要问题有:

  • 安全性取决于基本平台、传输机制和安全服务提供程序(NTLM、Kerberos 等等)并且与它们紧密集成。

  • 安全性是在点对点的基础上应用的,无法通过中间应用程序节点提供多个跃点和路由。

应用程序级安全性

通过使用这种方法,应用程序负责提供安全性并使用自定义的安全功能。例如:

  • 应用程序可以使用自定义的 SOAP 标头传递用户凭证,以便根据每个 Web 服务请求对用户进行身份验证。常用的方法是在 SOAP 标头中传递票证(或者用户名或许可证)。

  • 应用程序可以灵活地生成其包含角色的 IPrincipal 对象。该对象可以是自定义类或 .NET ¿ò¼Ü提供的 GenericPrincipal 类。

  • 应用程序可以有选择地加密需要保密的内容,但是这需要使用安全密钥存储,并且开发人员必须了解相关加密 API 的知识。

另一种方法是使用 SSL 提供机密性和完整性,并将它与自定义的 SOAP 标头结合起来以执行身份验证。

何时使用

在以下时候使用此方法:

  • 您想要利用在现有应用程序中使用的用户和角色的现有数据库架构。

  • 您想要加密消息的一部分,而不是整个数据流。

消息级(端对端)安全性

这是一种灵活性最大而且功能最强的方法,GXA 提案(特别是在 WS-Security 规范中)使用的就是这种方法。 2 阐释了消息级安全性。

f10sn02

2. 消息级安全性

WS-Security 规范说明了 SOAP 消息传递的增强功能,这些功能提供了消息完整性、消息机密性以及单次消息身份验证。

  • 身份验证是由在 SOAP 标头中传递的安全性令牌提供的。 WS-Security 不要求使用任何特定类型的令牌。安全令牌可以包括 Kerberos 票证、X.509 证书或自定义的二进制令牌。

  • 安全通信是通过数字签名提供的,以便确保消息的完整性,并使用 XML 加密以确保消息的机密性。

何时使用

可以使用 WS-Security 构建框架以便在异类 Web 服务环境中交换安全消息。它非常适合于不能直接控制终结点和中间应用程序节点配置的异类环境和方案。

消息级安全性:

  • 可以不依赖于基本传输。

  • 支持异类安全性体系结构。

  • 提供端对端的安全性并通过中间应用程序节点提供消息路由。

  • 支持多项加密技术。

  • 支持不可否认性。

Web 服务开发工具包

Web 服务开发工具包提供管理安全性所需的 API 以及路由和消息级检索等其他服务。该工具包符合最新的 Web 服务标准(例如 WS-Security 规范),因此,它支持与采用相同规范的其他供应商之间的互操作性。

更多信息
  • 有关 Web 服务开发工具包和 WS-Security 规范的最新消息,请参见 MSDN 中的“XML 开发人员中心”页面:http://msdn.microsoft.com/webservices/.

  • 有关 GXA 的详细信息,请参见 MSDN 上的文章“Understanding GXA”。

  • 有关该主题的讨论,请参考 MSDN 上的“GXA 互操作性新闻组”。

平台/传输安全性体系结构

3 显示了 ASP.NET Web 服务平台安全性体系结构。

f10sn03

3. Web 服务安全性体系结构

3 阐释了 ASP.NET Web 服务提供的身份验证和授权机制。当客户端调用 Web 服务时,将按下列顺序激发身份验证和授权事件:

  1. 接收到来自网络的 SOAP 请求。它是否包含身份验证凭证取决于所使用的身份验证类型。

  2. IIS 可以有选择地使用基本、摘要、集成(NTLM 或 Kerberos)或证书身份验证对调用者进行身份验证。在不能使用 IIS (Windows) 身份验证的异类环境中,可以将 IIS 配置为使用匿名身份验证。在这个方案中,可以使用消息级属性(例如,在 SOAP 标头中传递的票证)对客户端进行身份验证。

  3. IIS 也可以配置为只接受来自特定 IP 地址的客户端计算机的请求。

  4. IIS 将已验证的调用者的 Windows 访问令牌传递给ASP.NET (如果将 Web 服务配置为使用匿名身份验证,则它可能是匿名 Internet 用户的访问令牌)。

  5. ASP.NET 对该调用者进行身份验证。如果将 ASP.NET 配置为使用 Windows 身份验证,则此时不会进行任何其他的身份验证;IIS 对调用者进行身份验证。

    如果使用的是非 Windows 身份验证方法,则将 ASP.NET 身份验证模式设置为“无”以使用自定义身份验证。

    Web 服务目前不支持表单和 Passport 身份验证。

  6. ASP.NET 通过使用 URL 授权和文件授权来授权访问所请求的 Web 服务(.asmx 文件),文件授权使用与 .asmx 文件关联的 NTFS 权限来确定是否将访问权限授予已验证身份的调用者。

    只能将文件授权用于 Windows 身份验证。

    对于细分的授权,还可以使用 .NET 角色(以声明方式或编程方式)确保授权调用者访问所请求的 Web 方法。

  7. Web 服务中的代码可以使用特定标识来访问本地和/或远程资源。在默认情况下,ASP.NET Web 服务不执行任何模拟,因此,配置的 ASP.NET 进程帐户提供该标识。也可以选择原调用者的标识或已配置的服务标识。

网关守卫

ASP.NET Web 服务中的网关守卫是:

  • IIS

    • 如果禁用 IIS 匿名身份验证,则 IIS 只允许来自已通过身份验证的用户的请求。

    • IP 地址限制

    可以将 IIS 配置为只允许来自具有特定 IP 地址的计算机的请求。

  • ASP.NET

    • 文件授权 HTTP 模块(仅用于 Windows 身份验证)

    • URL 授权 HTTP 模块

  • 主体权限要求和明确的角色检查

更多信息
  • 有关网关守卫的详细信息,请参见“ASP.NET 安全性”一章中“ASP.NET 安全性体系结构”部分的“网关守卫”主题。

  • 有关配置安全性的详细信息,请参见本章后面的“配置安全性”。

身份验证和授权策略

本节介绍一组常用身份验证方案的可用授权选项(可进行配置和编程)。

下面概述了一些身份验证方案:

  • 带模拟功能的 Windows 身份验证

  • 不带模拟功能的 Windows 身份验证

  • 使用固定标识的 Windows 身份验证

带模拟功能的Windows 身份验证

以下配置元素向您显示了如何明确启用 Web.config 或Machine.config 中的 Windows (IIS) 身份验证和模拟功能。

应根据 Web 服务的具体情况,在每个 Web 服务的 Web.config 文件中配置身份验证。

<authentication mode="Windows" />
<identity impersonate="true" />

在此配置中,Web 服务代码模拟已由 IIS 验证身份的调用者。要模拟原调用者,您必须在 IIS 中关闭匿名访问。借助于匿名访问,Web 服务代码可以模拟匿名 Internet 用户帐户(在默认情况下,该帐户为 IUSR_MACHINE)。

可配置的安全设置

当您将 Windows 身份验证和模拟功能一起使用时,就可以使用下列授权选项:

  • Windows 访问控制列表 (ACL)

    • Web 服务 (.asmx) 文件。文件授权使用原调用者的安全性上下文对请求的 ASP.NET 资源(包括 .asmx Web 服务文件)执行访问检查。必须至少授权原调用者读取 .asmx 文件的权限。

    • Web 服务访问的资源。Web 服务所访问的资源(文件、文件夹、注册表项和 Active Directory_ 目录服务对象等等)的 Windows ACL 必须包含一个访问控制项 (ACE),该访问控制项授予原调用者“读”权限(因为用于资源访问的 Web 服务线程正在模拟该调用者)。

  • URL 授权。这是在 Machine.config 和/或 Web.config 中配置的。在 Windows 身份验证中,用户名采用 DomainName\UserName 格式,并且角色与 Windows 组一一对应。

    <authorization>
        <deny user="DomainName\UserName" />
        <allow roles="DomainName\WindowsGroup" />
        </authorization>
        

编程安全性

编程安全性是指您的 Web 服务代码中的安全性检查。在您使用 Windows 身份验证和模拟功能时,可以使用下列程序安全设置选项:

  • 主体权 限要求 命令性(嵌入方法的代码内)

        PrincipalPermission permCheck = new PrincipalPermission(
        null, @"DomainName\WindowsGroup");
        permCheck.Demand();
        
  • 声明性(这些属性可以优先于 Web 方法或 Web 类)

    // Demand that the caller is a member of a specific role (for Windows
        // authentication this is the same as a Windows group)
        [PrincipalPermission(SecurityAction.Demand,
        Role=@"DomainName\WindowsGroup")]
        // Demand that the caller is a specific user
        [PrincipalPermission(SecurityAction.Demand,
        Name=@"DomainName\UserName")]
        
  • 明确的角色检查。您可以使用 IPrincipal 接口执行角色检查。

    IPrincipal.IsInRole(@"DomainName\WindowsGroup");
        
何时使用

使用 Windows 身份验证和模拟的情况是:

  • Web 服务的客户端可以通过使用 Windows 帐户来标识,而 Windows 帐户则可以由服务器验证。

  • 您需要通过 Web 服务将原调用者的安全性上下文传递到下一层。例如,传递到一组使用 Enterprise Services (COM+) 角色的服务组件,或传递到需要细化(每用户)授权的数据层。

  • 您需要将原调用者的安全性上下文传递到下游各层以支持操作系统级审核。

重要 使用模拟功能可能会降低可扩展性,因为它会影响数据库连接池。作为一个替代方法,可以考虑使用受信任的子系统模型;在该模型中,Web 服务对调用者进行授权并使用固定标识来访问数据库。可以在应用程序级别上传递调用者标识;例如,使用存储过程参数来传递。

更多信息
  • 有关 Windows 身份验证和模拟的详细信息,请参见“ASP.NET Security”一章。

  • 有关 URL 授权的详细信息,请参见“ASP.NET Security”一章中的“URL 授权注意事项”。

不带模拟功能的 Windows 身份验证

下列配置显示了如何在 Web.config 中明确声明启用不带模拟功能的 Windows (IIS) 身份验证。

<authentication mode="Windows" />
<!-- The following setting is equivalent to having no identity element -->
<identity impersonate="false" />
可配置的安全性

当您使用不带模拟功能的 Windows 身份验证时,可以使用以下授权选项:

  • Windows ACL

    • Web 服务 (.asmx) 文件.文件授权使用原调用者对请求的 ASP.NET 资源(包括 .asmx Web 服务文件)执行访问检查。模拟不是必需选项。

    • 应用程序访问的资源。应用程序所访问的资源(文件、文件夹、注册表项和 Active Directory 对象等)的 Windows ACL 必须包含一个 ACE,它授予 ASP.NET 进程标识(访问资源时 Web 服务线程所使用的默认标识)“读”权限。

  • URL 授权

    这是在Machine.config 和 Web.config 中配置的。在 Windows 身份验证中,用户名采用 DomainName\UserName 格式,并且角色与 Windows 组一一对应。

    <authorization>
        <deny user="DomainName\UserName" />
        <allow roles="DomainName\WindowsGroup" />
        </authorization>
        
编程安全性

编程安全性是指您的 Web 服务代码中的安全性检查。当您使用不带模拟功能的 Windows 身份验证时,可以使用下列编程安全性选项:

  • 主体权限要求

    • 命令性

          PrincipalPermission permCheck = new PrincipalPermission(
              null, @"DomainName\WindowsGroup");
              permCheck.Demand();
              
    • 声明性

      // Demand that the caller is a member of a specific role (for Windows
              // authentication this is the same as a Windows group)
              [PrincipalPermission(SecurityAction.Demand,
              Role=@"DomainName\WindowsGroup")]
              // Demand that the caller is a specific user
              [PrincipalPermission(SecurityAction.Demand,
              Name=@"DomainName\UserName")]
              
  • 明确的角色检查。您可以使用 IPrincipal 接口执行角色检查。

    IPrincipal.IsInRole(@"DomainName\WindowsGroup");
        
何时使用

使用不带模拟功能的 Windows 身份验证的情况:

  • Web 服务的客户端可以通过使用 Windows 帐户来标识,而 Windows 帐户则可以由服务器验证。

  • 您需要使用受信任的子系统模型并且在 Web 服务中对客户端进行授权,然后使用固定标识访问下游资源(例如数据库),从而为连接池提供支持。

更多信息
  • 有关 Windows 身份验证和模拟的详细信息,请参见“ASP.NET 安全性”一章。

  • 有关 URL 授权的详细信息,请参见“ASP.NET 安全性”一章中的“URL 授权注意事项”。

使用固定标识的 Windows 身份验证

Web.config 中的 <identity> 元素支持可选的用户名和密码属性,可以使用该元素为 Web 服务配置特定的固定标识以进行模拟。这显示在以下配置文件片段中。

<identity impersonate="true"
userName="registry:HKLM\SOFTWARE\YourSecureApp\
identity\ASPNET_SETREG,userName"
password="registry:HKLM\SOFTWARE\YourSecureApp\
identity\ASPNET_SETREG,password" />

本示例显示了 <identity> 元素,其中凭证使用 aspnet_setreg.exe 实用工具在注册表中进行加密。明文形式的 userNamepassword 属性值被指向包含加密凭证的安全注册表项和命名值替代。有关此实用工具的详细信息及下载,请参见 Microsoft 知识库中的文章Q329290“HOW TO:Use the ASP.NET Utility to Encrypt Credentials and Session State Connection Strings”。

何时使用

当在 Windows 2000 服务器上使用 .NET Framework 1.0 时,不推荐使用固定的模拟标识。这是因为您需要授予 ASP.NET 进程帐户“充当操作系统的一部分”权限。 ASP.NET 进程需要此权限,因为它使用您提供的凭证执行 LogonUser 调用。

.NET Framework 1.1 版会在 Windows 2000 中为此方案进行改进。登录会由 IIS 进程执行,因此 ASP.NET 不需要“充当操作系统的一部分”权限。

更多信息

  • 有关 Windows 身份验证和模拟的详细信息,请参见“ASP.NET 安全性一章”。

  • 有关 URL 授权的详细信息,请参见“ASP.NET 安全性”一章中的“URL 授权注意事项”。

配置安全性

本节说明配置 ASP.NET Web 服务安全性所需的实际步骤。 4 总结了这些情况。

f08sn03

4. 配置 ASP.NET Web 服务安全性

配置 IIS 设置

有关如何配置 IIS 安全设置的详细信息,请参见“ASP.NET 安全性”一章中的“配置安全性”,因为该信息也适用于 ASP.NET Web 服务。

配置 ASP.NET 设置

应用程序级配置设置保存在 Web.config 文件中,该文件位于 Web 服务的虚拟根目录中。请配置以下设置:

  1. 配置身份验证。应该在 Web 服务虚拟根目录下的 Web.config 文件中基于每个 Web 服务对它进行设置(而不是在 Machine.config 中)。

    <authentication mode="Windows|None" />
        

    Web 服务目录不支持 Passport 或表单身份验证。对于自定义和消息级身份验证,请将模式设置为“无”。

  2. 配置模拟和授权。有关详细信息,请参见“ASP.NET 安全性”一章中的“配置安全性”。

更多信息

有关 URL 授权的详细信息,请参见“ASP.NET 安全性”一章中的“URL 授权注意事项”。

保护资源

应该使用“ASP.NET 安全性”一章中介绍的相同方法来保护 Web 资源的安全。另外,对于 Web 服务,应该考虑从生产服务器上的 Machine.config 中删除 HTTP-GET 和 HTTP-POST 协议。

禁用 HTTP-GET、HTTP-POST

默认情况下,客户端可以使用以下三个协议与 ASP.NET Web 服务进行通信:HTTP-GET、HTTP-POST 和 HTTP 上的 SOAP。应该在生产计算机上禁用计算机级别的 HTTP-GET 和 HTTP-POST 协议支持,因为生产计算机不需要这两个协议。这可避免出现潜在的安全隐患,使有害的 Web 页面无法访问在防火墙后面运行的内部 Web 服务。

禁用这些协议意味着,新客户端将无法使用 Web 服务测试页中的 Invoke 按钮来测试 XML Web 服务。相反,您必须使用 Microsoft Visual Studio_ .NET 开发系统添加对 Web 服务的引用,以便创建一个测试客户端程序。您可能需要在开发计算机上启用这些协议,使开发人员能够使用测试页进行测试。

在整个计算机中禁用 HTTP-GET 和 HTTP-POST 协议
  1. 编辑 Machine.config。

  2. 在 <webServices> 元素中,注释掉 HTTP-GET 和 HTTP-POST 支持的命令行。完成后,Machine.config 应该如下所示。

    <webServices>
        <protocols>
        <add name="HttpSoap"/>
        <!-- <add name="HttpPost"/> -->
        <!-- <add name="HttpGet"/>  -->
        <add name="Documentation"/>
        </protocols>
        </webServices>
        
  3. 保存 Machine.config。

    在特殊情况下,Web 服务客户端使用 HTTP-GET 或 HTTP-POST 与 Web 服务进行通信,您可以在应用程序的 Web.config 文件中添加对这些协议的支持,方法是:创建 <webServices>,然后使用 <protocol> 和 <add> 元素添加对这些协议的支持(如上所示)。

更多信息

有关保护资源安全的详细信息,请参见“ASP.NET 安全性”一章中的“配置安全性”。

安全通信

结合使用 SSL 和 IPSec 来保护通信链路的安全。

更多信息

将身份验证的凭证传递给 Web 服务

在调用 Web 服务时,您可以使用 Web 服务代理来完成该操作;Web 服务代理是一个本地对象,它公开一组与目标 Web 服务相同的方法。

可以使用 Wsdl.exe 命令行实用工具来生成 Web 服务代理。另外,如果您使用 Visual Studio .NET,则还可以通过在项目中添加 Web 引用来生成代理。

对于要为其生成代理的 Web 服务,如果将它配置为需要使用客户端证书,则在添加引用时必须暂时禁用该要求,否则就会出现错误。在添加引用后,必须记住将该服务重新配置为需要使用证书。

另一个方法是给用户应用程序提供脱机的 Web 服务描述语言 (WSDL) 文件。如果 Web 服务接口发生变化,则必须记住对它进行更新。

指定用于 Windows 身份验证的客户端凭证

如果您正在使用 Windows 身份验证,则必须使用 Web 服务代理的 Credentials 属性指定用于身份验证的凭证。如果您没有明确地设置该属性,则无需任何凭证即可调用 Web 服务。如果需要 Windows 身份验证,这会导致出现 HTTP 状态 401,拒绝访问响应。

使用 DefaultCredentials

不能隐式地传递客户端凭证。Web 服务使用者必须在代理上设置凭证和身份验证详细信息。要将客户端的 Windows 安全性上下文(通过模拟线程令牌或进程令牌)传递给 Web 服务,您可以将 Web 服务的 Credentials 属性设置为 CredentialCache. DefaultCredentials (如下所示)。

proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;

在使用此方法之前,请注意以下事项:

  • 仅当使用 NTLM、Kerberos 或协商身份验证时,此方法才传递客户端凭证。

  • 如果客户端应用程序(例如,Windows 表单应用程序)调用 Web 服务,则可以从用户的交互式登录会话中获取凭证。

  • 除非配置了模拟功能(此时,服务器端应用程序使用被模拟的调用者的标识),否则,服务器端应用程序(例如,ASP.NET Web 应用程序)使用进程标识。

使用特定凭证

若要在调用 Web 服务时使用一组特定的身份验证凭证,请使用以下代码。

CredentialCache cache = new CredentialCache();
cache.Add( new Uri(proxy.Url), // Web service URL
"Negotiate",        // Kerberos or NTLM
new NetworkCredential("username", "password", "domainname") );
proxy.Credentials = cache;

在上面的示例中,请求的协商身份验证类型导致 Kerberos 或 NTLM 身份验证。

请求特定的身份验证类型

如以下所述,您应该请求特定的身份验证类型。避免直接使用 NetworkCredential 类,如以下代码所示。

proxy.Credentials = new
NetworkCredential("username", "password", "domainname");

在生产代码中应该避免出现这种情况,因为您无法控制 Web 服务使用的身份验证机制,因此也无法控制使用凭证的方式。

例如,可能期望得到来自服务器的 Kerberos 或 NTLM 身份验证质询,但实际却可能收到一个基本质询。在这种情况下,会以明文形式将提供的用户名和密码发送到服务器。

设置 PreAuthenticate 属性

可以将代理的 PreAuthenticate 属性设置为 true 或 false。将其设置为 true 可以提供特定的身份验证凭证,以便通过 Web 请求传递 WWW-authenticate HTTP 标头。这可以避免 Web 服务器拒绝请求的访问,并在后续重试请求中执行身份验证。

仅当 Web 服务第一次成功地进行身份验证后,才能使用预身份验证。预身份验证对第一次 Web 请求没有任何影响。

private void ConfigureProxy( WebClientProtocol proxy,
string domain, string username,
string password )
{
// To improve performance, force pre-authentication
proxy.PreAuthenticate = true;
// Set the credentials
CredentialCache cache = new CredentialCache();
cache.Add( new Uri(proxy.Url),
"Negotiate",
new NetworkCredential(username, password, domain) );
proxy.Credentials = cache;
proxy.ConnectionGroupName = username;
}

使用 ConnectionGroupName 属性

注意,上述代码设置 Web 服务代理的 ConnectionGroupName 属性。仅当用于连接 Web 服务的安全性上下文根据不同请求发生变化时,才需要使用该属性(如下所述)。

如果 ASP.NET Web 应用程序连接到 Web 服务并传递原调用者的安全性上下文(通过使用 DefaultCredentials 或者设置显式凭证,如上所示),则应该在 Web 应用程序中设置 Web 服务代理的 ConnectionGroupName 属性。这可防止未验证身份的新客户端重用到 Web 服务(该服务与以前的客户端身份验证凭证关联)的已验证身份的旧 TCP 连接。在使用 HTTP KeepAlives 或出于 IIS 的性能考虑而启用身份验证持续功能时,会出现连接重用。

ConnectionGroupName 属性设置为能够区分调用者的标识符(例如调用者的用户名),如上面的代码片段所示。

如果没有通过 Web 应用程序将原调用者的安全性上下文传递给 Web 服务,而是,Web 应用程序使用固定标识(例如,Web 应用程序的 ASP.NET 进程标识)连接到 Web 服务,则不需要设置 ConnectionGroupName 属性。在此方案中,连接安全性上下文在从一个调用者传递到下一个调用者时,保持不变。

从非 Windows 客户端调用 Web 服务

可以将多种身份验证方法用于跨浏览器的方案中。它们是:

代理服务器身份验证

Visual Studio .NET 的 添加 Web 引用 对话框不支持代理服务器身份验证(但是,下一版本的 Visual Studio .NET 对它提供支持)。因此,在添加 Web 引用时,可能会出现 HTTP 状态 407 响应:“需要代理验证”。

通过浏览器查看 .asmx 文件时,可能看不到此错误,因为浏览器自动发送凭证。

要解决这个问题,可以使用 Wsdl.exe 命令行实用工具(而不是 添加 Web 引用 对话框),如下所示。

wsdl.exe /proxy:http:// /pu: /pp: /pd: http://www.YouWebServer.com/YourWebService/YourService.asmx

如果您需要以编程方式设置代理服务器身份验证信息,请使用以下代码。

YourWebServiceProxy.Proxy.Credentials = CredentialsCache.DefaultCredentials;

传送原调用者

本节介绍如何通过 ASP.NET Web 应用程序将原调用者的安全性上下文传递给远程应用程序服务器上的 Web 服务。要在 Web 服务或后续下游子系统(例如,数据库,您要在其中授权原调用者访问个别数据库对象)中执行每用户授权,您需要完成此操作。

5 中,通过驻留 ASP.NET Web 应用程序的前端 Web 服务器将原调用者 (Alice) 的安全性上下文传递给远程应用程序服务器上 ASP.NET 驻留的远程对象,并最终将其传递到后端数据库服务器。

f10sn05

5. 传递原调用者的安全性上下文

为了向 Web 服务传递凭证,Web 服务客户端(此方案中的 ASP.NET Web 应用程序)必须配置 Web 服务代理,并明确地设置该代理的 Credentials 属性,如本章前面的“将身份验证的凭证传递给 Web 服务”所述。

可以使用两种方法来传递调用者的上下文。

  • 传递默认凭证并使用 Kerberos 身份验证(和委派)。该方法要求您在 ASP.NET Web 应用程序内使用模拟,并用从被模拟调用者的安全性上下文中获得 DefaultCredentials 来配置远程对象代理。

  • 传递显式凭证并使用基本身份验证或表单身份验证。该方法不要求在 ASP.NET Web 应用程序内使用模拟。相反,您可以通过编程方式,使用从给 Web 应用程序提供的服务器变量(利用基本身份验证)或 HTML 表单字段(利用表单身份验证)中获取的显式凭证来配置 Web 服务代理。可以使用基本身份验证或表单身份验证,以明文形式给服务器提供用户名和密码。

带有 Kerberos 委派的默认凭证

要使用 Kerberos 委派,所有计算机(服务器和客户端)都必须运行 Windows 2000 或更高版本。此外,必须将要委派的客户端帐户存储在 Active Directory 中,并且不能将其标记为“敏感用户,不能被委派”。

以下表格显示了在 Web 服务器和应用程序服务器上需要执行的配置步骤。

配置 Web 服务器

配置 IIS

步骤

更多信息

禁用对 Web 应用程序的虚拟根目录的匿名访问

对 Web 应用程序的虚拟根目录启用 Windows 集成身份验证




假定客户端和服务器运行的是 Windows 2000 或更高版本,则可以对 Kerberos 身份验证进行协商。
注: 如果在 Windows 2000 上使用 Internet Explorer 6,则它默认使用 NTLM 身份验证,而不是所需的 Kerberos 身份验证。要启用 Kerberos 委派,请参见 Microsoft 知识库文章 Q299838“Unable to Negotiate Kerberos Authentication after upgrading to Internet Explorer 6”。

配置 ASP.NET

 

步骤

更多信息

将 ASP.NET Web 应用程序配置为使用 Windows 身份验证

编辑 Web 应用程序的虚拟目录下的 Web.config
将 <authentication> 元素设置为:

<authentication mode="Windows" />

-

-

-

配置 ASP.NET Web 应用程序的模拟

编辑 Web 应用程序的虚拟目录下的 Web.config
将 <identity> 元素设置为:

-

<identity impersonate="true" />

配置 Web 服务代理

 

步骤

更多信息

将 Web 服务代理的凭证属性设置为 DefaultCredentials

有关代码示例,请参见本章前面的“使用 DefaultCredentials”。

配置远程应用程序服务器

配置 IIS

 

步骤

更多信息

禁用对 Web 服务的虚拟根目录的匿名访问

对 Web 应用程序的虚拟根目录启用 Windows 集成身份验证

 

配置 ASP.NET Web 服务主机)

 

步骤

更多信息

将 ASP.NET 配置为使用 Windows 身份验证

编辑 Web 服务的虚拟目录下的 Web.config 文件。
将 <authentication> 元素设置为:

配置 ASP.NET 的模拟功能

编辑 Web 服务的虚拟目录下的 Web.config 文件。
将 <identity> 元素设置为:

注: 只有当您想将原调用者的安全性上下文通过 Web 服务传递给下一个下游子系统(例如数据库)时,才需要执行本步骤。如果在此处启用了模拟功能,资源访问(本地和远程)就会使用模拟的原调用者的安全性上下文。
如果您只要求在 Web 服务中对每个用户进行授权检查,则无须在此处启用模拟功能。

更多信息

有关配置 Kerberos 委派的更多信息,请参见“How To Implement Kerberos Delegation for Windows 2000”。

带有基本身份验证或表单身份验证的显式凭证

作为 Kerberos 委派的一个替代方法,您可以在 Web 应用程序中使用基本身份验证或表单身份验证来捕获客户端凭证,然后对 Web 服务使用基本身份验证(或者集成 Windows 身份验证)。

利用此方法,Web 应用程序可以使用客户端的明文凭证。可通过 Web 服务代理将这些凭证传递给 Web 服务。为此,必须在 Web 应用程序中编写代码来检索客户端凭证并配置代理。

基本身份验证

使用基本身份验证,Web 应用程序可在服务器变量中使用原调用者的凭证。以下代码说明如何检索凭证并配置 Web 服务代理。

// Retrieve client's credentials (available with Basic authentication)
string pwd = Request.ServerVariables["AUTH_PASSWORD"];
string uid = Request.ServerVariables["AUTH_USER"];
// Associate the credentials with the Web service proxy
// To improve performance, force preauthentication
proxy.PreAuthenticate = true;
// Set the credentials
CredentialCache cache = new CredentialCache();
cache.Add( new Uri(proxy.Url),
"Basic",
new NetworkCredential(uid, pwd, domain) );
proxy.Credentials = cache;
表单身份验证

使用表单身份验证,Web 应用程序可在表单各个字段中(而不是在服务器变量中)使用原调用者的凭证。在这种情况下,请使用以下代码。

// Retrieve client's credentials from the logon form
string pwd = txtPassword.Text;
string uid = txtUid.Text;
// Associate the credentials with the Web service proxy
// To improve performance, force preauthentication
proxy.PreAuthenticate = true;
// Set the credentials
CredentialCache cache = new CredentialCache();
cache.Add( new Uri(proxy.Url),
"Basic",
new NetworkCredential(uid, pwd, domain) );
proxy.Credentials = cache;

以下各表显示了在 Web 服务器和应用程序服务器上需要执行的配置步骤。

配置 Web 服务器

配置 IIS

步骤

更多信息

要使用基本身份验证,请禁用对 Web 应用程序的虚拟根目录的匿名访问,并选择基本身份验证

- 或 -

要使用表单身份验证,请启用匿名访问

基本身份验证和表单身份验证都应和 SSL 配合使用,才能保护通过网络传送的明文凭证。如果您使用基本身份验证,则应该将 SSL 用于所有页面(而不仅仅是初始登录页面),因为在每个请求中都传递基本身份验证凭证。



类似地,如果您使用表单身份验证,则应该将 SSL 用于所有页面,以保护初始登录中的明文凭证以及在后续请求中传递的身份验证票证。

配置 ASP.NET

 

步骤

更多信息

如果您使用基本身份验证,请将您的 ASP.NET Web 应用程序配置为使用 Windows 身份验证

- 或 -

如果您使用表单身份验证,请将您的 ASP.NET Web 应用程序配置为使用表单身份验证

编辑 Web 应用程序的虚拟目录下的 Web.config
将 <authentication> 元素设置为:

- 或 -

编辑 Web 应用程序的虚拟目录下的 Web.config
将<authentication> 元素设置为:

禁用 ASP.NET Web 应用程序中的模拟

编辑 Web 应用程序的虚拟目录中的 Web.config。
将 <identity> 元素设置为:

注: 这相当于没有 <identity> 元素。
由于通过代理将用户凭证明确地传递给 Web 服务,因此不需要使用模拟功能。

配置 Web 服务代理

 

步骤

更多信息

编写代理以便在 Web 服务代理中捕获和明确地设置凭证

请参考前面的“基本身份验证”和“表单身份验证”部分中显示的代码片段。

配置应用程序服务器

配置 IIS

步骤

更多信息

禁用对应用程序的虚拟根目录的匿名访问

启用基本身份验证




注: 通过在(Web 服务)应用程序服务器上使用基本身份验证,Web 服务可以将原调用者的安全性上下文传递到数据库(因为调用者的用户名和密码采用明文形式,并且可用于响应来自数据库服务器的网络身份验证质询)。
如果不需要将原调用者的安全性上下文传递到 Web 服务以外,请考虑在应用程序服务器上将 IIS 配置为使用 Windows 集成身份验证,因为这可提供更高的安全性–(不通过网络传递凭证,并且不给 Web 服务提供凭证)。

配置 ASP.NET Web 服务)

 

步骤

更多信息

将 ASP.NET 配置为使用 Windows 身份验证

编辑 Web 服务的虚拟目录下的 Web.config。
将 <authentication> 元素设置为:

将 ASP.NET Web 服务配置为使用模拟

编辑 Web 服务的虚拟目录下的 Web.config。
将 <identity> 元素设置为:

注: 只有当您想将原调用者的安全性上下文通过 Web 服务传递给下一个下游子系统(例如数据库)时,才需要执行本步骤。如果在此处启用了模拟功能,资源访问(本地和远程)就会使用模拟的原调用者的安全性上下文。
如果您只要求在 Web 服务中对每个用户进行授权检查,则无须在此处启用模拟功能。

受信任的子系统

受信任的子系统模型提供一种替代(且更易于实现的)方法来传递原调用者的安全性上下文。在该模型中,Web 服务和 Web 应用程序之间存在信任边界。Web 服务首先信任 Web 应用程序对调用者正确地进行身份验证和授权,然后才允许其向 Web 服务发送请求。在 Web 服务中,不对原调用者进行任何身份验证。Web 服务对 Web 应用程序用来与 Web 服务通信的固定受信任标识进行身份验证。在大多数情况下,这是 ASP.NET 辅助进程的进程标识。

6 显示了受信任的子系统模型。

f10sn06

6. 受信任的子系统模型

传递调用者的标识

如果您使用的是受信任的子系统模型,则可能仍然需要传送原调用者的标识(名称,而不是安全性上下文),例如,用于在数据库中进行审核。

通过使用可用于从数据库检索用户特定数据的方法、存储过程参数和受信任的查询参数(如下面的示例所示),可以在应用程序级传送该标识。

SELECT x,y,z FROM SomeTable WHERE UserName = "Alice"

配置步骤

以下各表显示了在 Web 服务器和应用程序服务器上需要执行的配置步骤。

配置 Web 服务器

配置 IIS

步骤

更多信息

配置 IIS 身份验证

Web 应用程序可以使用任何形式的验证方法来验证原调用者。

配置 ASP.NET

 

步骤

更多信息

配置身份验证并确保禁用模拟功能

编辑 Web 应用程序的虚拟目录下的 Web.config。
将 <authentication> 元素设置为“Windows”、“Forms”或“Passport”。

将 <identity> 元素设置为:

(或删除 <identity> 元素)

重置用于运行 ASP.NET 的 ASPNET 帐户的密码,或者创建一个权限最少的域帐户来运行ASP.NET,并在 Web.config 中的 <processModel> 元素上指定帐户详细信息

有关如何从 ASP.NET 访问网络资源(包括 Web 服务)以及选择和配置 ASP.NET 进程帐户的详细信息,请参见“ASP.NET 安全性”一章中的“访问网络资源”和“ASP.NET 的进程标识”。

配置 Web 服务代理

 

步骤

更多信息

配置 Web 服务代理,以便将默认凭证用于 Web 服务的所有调用

使用以下代码行:

proxy.Credentials = DefaultCredentials;
配置应用程序服务器

配置 IIS

步骤

更多信息

禁用对 Web 服务的虚拟根目录的匿名访问

启用 Windows 集成的身份验证

 

配置 ASP.NET

 

步骤

更多信息

将 ASP.NET 配置为使用 Windows 身份验证

编辑 Web 服务的虚拟目录下的 Web.config。
将 <authentication> 元素设置为:

<authentication mode="Windows" />

禁用模拟

编辑应用程序的虚拟目录下的 Web.config。
将 <identity> 元素设置为:

访问系统资源

有关从 ASP.NET Web 服务访问系统资源(例如,事件日志和注册表(的详细信息,请参见“ASP.NET 安全性”一章中的“访问系统资源”。该章讨论的方法和限制也适用于 ASP.NET Web 服务。

访问网络资源

在从 Web 服务访问网络资源时,您需要考虑用于响应来自远程计算机的网络身份验证质询的标识。您有三个选项:

  • 进程标识(由用于运行 ASP.NET 辅助进程的帐户确定)

  • 服务标识(例如,通过调用 LogonUser 创建的标识)

  • 原调用者标识(带有为模拟配置的 Web 服务)

有关每种方法的相对优点的详细信息,请参见“ASP.NET 安全性”一章中的“访问网络资源”。

访问 COM 对象

Web 服务不能使用 AspCompat 指令(由 Web 应用程序在调用单元线程 COM 对象时使用)。这意味着,在从 Web 服务调用单元模型对象时,就会发生线程转换。这会对性能造成轻微的影响,如果 Web 服务使用模拟功能,则在调用 COM 组件时将会丢失模拟令牌。这通常导致出现“拒绝访问”异常错误。

更多信息

将客户端证书用于 Web 服务

本节介绍在 Web 服务身份验证中使用 X.509 客户端证书的方法。

可以在 Web 服务中使用客户端证书身份验证来验证:

  • 其他 Web 服务。

  • 与 Web 服务直接进行通信的应用程序(例如,基于服务器或客户端的桌面应用程序)。

使用证书对 Web 浏览器客户端进行身份验证

Web 服务不能使用客户端证书验证调用者是否与中间 Web 应用程序交互,因为无法将原调用者的证书通过 Web 应用程序传递给 Web 服务。虽然 Web 应用程序可以使用证书对其客户端进行身份验证,但 Web 服务无法使用相同的证书进行身份验证。

这种服务器到服务器的方案失败的原因在于,Web 应用程序无法访问其证书存储中的客户端证书(特别是其私钥)。 7 说明了这个问题。

f10sn07

7. Web 服务客户端证书身份验证

使用受信任的子系统模型

要消除上述限制并在 Web 服务中支持证书身份验证,必须使用受信任的子系统模型。通过使用这种方法,Web 服务可以使用 Web 应用程序的证书(而不是原调用者的证书)对 Web 应用程序进行身份验证。Web 服务必须信任 Web 应用程序对其用户进行身份验证并进行必要的授权,确保只有经过授权的调用者才能够访问 Web 服务提供的数据和功能。

8 显示了这种方法。

f10sn08

8. Web 服务对受信任的 Web 应用程序进行身份验证

如果 Web 服务中的授权逻辑需要多个角色,则 Web 应用程序可以根据调用者的角色成员身份来发送不同的证书。例如,可以对管理员组的成员使用一个证书(允许他们在后端数据库中更新数据);而对所有其他用户使用另一个证书(只授予他们“读”操作权限)。

在此类方案中,本地证书服务器(只能通过两个服务器访问)可用于管理所有的 Web 应用程序证书。

在这个方案中:

  • Web 应用程序使用客户端证书对其用户进行身份验证。

  • Web 应用程序充当网关守卫,对其用户进行授权以及控制对 Web 服务的访问。

  • Web 应用程序调用 Web 服务并传递另一个代表该应用程序的证书(也可能是基于调用者角色成员身份的一组证书)。

  • Web 服务对 Web 应用程序进行身份验证,然后信任该应用程序执行必要的客户端授权。

  • 在 Web 应用程序服务器和 Web 服务服务器之间,使用 IPSec 提供额外的访问控制。IPSec 禁止通过其他计算机进行未经授权的访问。Web 服务服务器上的证书身份验证也可以防止未经授权的访问。

解决方案实现

在此方案中,要在 Web 服务中使用证书身份验证,请使用单独的进程来调用 Web 服务和传递证书。您无法从 ASP.NET Web 应用程序中直接使用证书,因为它没有加载用户配置文件及其相关的证书存储。必须将此单独的进程配置为使用具有相关用户配置文件(和证书存储)的帐户来运行。您有两个主要的选项:

  • 使用 Enterprise Services 服务器应用程序

  • 使用 Windows 服务。

9 说明了包含 Enterprise Services 服务器应用程序的方案。

f10sn09

9. Web 服务中的客户端证书身份验证

下面概述了 9 中说明的事件顺序:

  1. Web 应用程序使用客户端证书对原调用者进行身份验证。

  2. Web 应用程序充当网关守卫,并且负责授权访问特定范围的功能(包括那些与 Web 服务进行交互的功能)。

  3. Web 应用程序调用在进程外 Enterprise Services 中运行的服务组件。

  4. 用于运行 Enterprise Services 应用程序的帐户具有相关的用户配置文件。该组件访问其证书存储中的客户端证书,Web 服务使用该证书对 Web 应用程序进行身份验证。

  5. 服务组件调用 Web 服务,并根据每个方法请求传递客户端证书。Web 服务使用该证书对 Web 应用程序进行身份验证,然后信任 Web 应用程序正确地向原调用者进行授权。

为什么使用其他进程?

由于需要用户配置文件(包含证书存储),因此要求使用其他进程(而不是使用 Aspnet_wp.exe Web 进程与 Web 服务建立联系)。

使用 ASPNET 帐户运行的 Web 应用程序没有访问 Web 服务器上任何证书的权限。这是因为,证书存储保存在与交互式用户帐户相关的用户配置文件中。仅当使用交互式帐户进行实际登录时,才会为该帐户创建用户配置文件。不能将 ASPNET 帐户用于交互式用户帐户;可以给其配置“拒绝交互式登录”权限以提高安全性。

重要 不要重新配置 ASPNET 帐户以删除此权限并将该帐户转换为交互式登录帐户。请使用配置的服务帐户运行单独的进程来访问证书,如本章前面所述。

更多信息

安全通信

安全通信是指通过网络在应用程序之间传送 Web 服务消息时确保消息的完整性和机密性。可以使用两种方法来解决这个问题:传输级选项和消息级选项。

传输级选项

传输级选项包括:

  • SSL

  • IPSec

如果满足以下条件,则可以使用这些选项:

  • 直接从应用程序向 Web 服务发送消息,并且不通过中间系统传递消息。

  • 可以控制参与消息传输的两个终结点的配置。

消息级选项

消息级方法可以确保消息通过任意数量的中间系统传递时的机密性和完整性。可以对消息进行签名以提供完整性。为了保证机密性,您可以选择加密整个消息或消息的一部分。

如果符合以下条件,则可以使用消息级方法:

  • 您向 Web 服务发送消息,并且可能会将消息转发到其他 Web 服务,或者通过中间系统进行传递。

  • 您无法控制两个终结点的配置,例如,您从一个公司向另一个公司发送消息。

更多信息

  • Web 服务开发工具包提供符合 WS-Security 规范的消息加密功能。

  • 有关 SSL 和 IPSec 的更多信息,请参见第 4 章“安全通信”。

小结

本章重点介绍了 ASP.NET、IIS 和操作系统的基本服务提供的平台/传输级(点对点)Web 服务安全性。虽然平台级安全性为紧密集成的 Intranet 应用提供了安全的解决方案,但它不适用于异类环境。为此,需要使用 GXA WS-Security 规范提供的消息级安全性。可以使用 Web 服务开发工具包来开发消息级 Web 服务安全性解决方案。

对于紧密集成的 Windows 域环境:

  • 如果您要将原调用者的标识从 ASP.NET Web 应用程序传递给远程 Web 服务,则 ASP.NET Web 应用程序应该使用 Kerberos 身份验证(将帐户配置为使用委派)、基本身份验证或表单身份验证。

    • 通过使用 Kerberos 身份验证,可以在 Web 应用程序中启用模拟功能,并使用 DefaultCredentials 来配置 Web 服务代理的 Credentials 属性。

    • 通过使用基本身份验证或表单身份验证,可以捕获调用者的凭证,并通过添加新的 CredentialCache 对象来设置 Web 服务代理的 Credentials 属性。

对于 Web 服务到 Web 服务的方案:

  • 使用基本身份验证或 Kerberos 身份验证,并在客户端代理中设置凭证。

  • 使用进程外 Enterprise Services 应用程序或 Windows 服务来使用来自 Web 应用程序的X.509 证书。

  • 尽可能地使用系统级授权检查(例如文件授权和 URL 授权)。

  • 对于细分的授权(例如,在 Web 方法级上),请使用 .NET 角色(通过声明性方式和命令性方式)。

  • 使用 .NET 角色来授权非 Windows 用户(基于包含角色的 GenericPrincipal 对象)。

  • 在生产服务器上禁用 HTTP-GET 和 HTTP-POST 协议。

  • 如果不担心通过中间系统安全地传递消息的问题,请使用传输级安全性。

  • 如果 SSL 性能可以接受,请使用传输级安全性。

  • 使用 WS-Security 和 Web 服务开发工具包来开发消息级解决方案。

 

Web 服务开发人员中心:安全、可靠、事务化的 Web 服务:结构和组合(Web 服务技术文章)

发布日期 : 4/1/2004 | 更新日期 : 5/28/2004

安全、可靠、事务化的 Web 服务:结构和组合

2003 年 9 月

IBM Corporation

Microsoft Corporation

Donald F. Ferguson

IBM 名士 (IBM Fellow) 兼主席

IBM Software Group Architecture Board

Brad Lovering

杰出工程师

Tony Storey

IBM 名士

John Shewchuk

Web 服务架构师

内容

引言

1.1 可组合的服务

1.2 实践中的组合示例

2.0 Web 服务:面向服务的结构

2.1 服务是通过架构和协定而不是类型描述的

2.2 服务兼容性多于类型兼容性

2.3 面向服务假定坏事情可能并且必将发生

2.4 面向服务支持服务的灵活绑定

3.0 Web 服务规范和功能

3.1 Web 服务的可组合方法

3.2 基础 — 传输和消息处理

3.2.1 传输 — HTTP、HTTP/S 和 SMTP

3.2.2 消息格式 — XSD

3.2.3 WS-Addressing

3.3 描述

3.3.1 WSDL

3.3.2 WS-Policy

3.3.3 获取描述

3.3.4 WS-MetadataExchange

3.3.5 UDDI

3.4 服务保证

3.5 安全性

3.5.1 WS-Security

3.5.2 WS-Trust

3.5.3 WS-SecureConversation

3.5.4 WS-Federation

3.6 可靠的消息处理

3.6.1 WS-ReliableMessaging

3.7 事务

3.7.1 WS-Coordination

3.7.2 WS-AtomicTransaction

3.7.3 WS-BusinessActivity

3.8 服务组合

3.8.1 BPEL4WS

4.0 实践中的 Web 服务 — 一个示例

4.1 第一部分:客户体验

4.2 第二部分:供应商体验

5.0 结束语

6.0 致谢

1.0 引言

当今,Web 服务 - 特别是处理 XML 编码的 SOAP 消息的、通过 HTTP 发送的、使用 Web 服务描述语言 (WSDL) 描述的分布式服务 - 正得到广泛的部署。(今天,XML、SOAP 和 HTTP 是通用的术语,但在许多方面,它们的用法已经超出了其最初的缩写词的含义。)出于完整性的考虑,在此列出这些缩写词:XML - eXtensible Markup Language(可扩展标记语言)、SOAP - Simple Object Access Protocol(简单对象访问协议)和 HTTP - HyperText Transfer Protocol(超文本传输协议)。Web 服务可用在各种各样的应用程序集成环境中:从简单的、即席的、防火墙后面的数据共享到大规模的 Internet 零售和货币交易。并且,Web 服务正越来越多地应用于移动通讯、设备和网络环境中。

Web 服务提供了软件组件之间的互操作性,这些软件组件可以在不同的公司之间进行通讯,并且可以驻留在不同的基础架构中。这解决了客户、软件开发人员和合作伙伴所面临的一个最重要的问题。HTTP 和 SOAP 提供了通讯和消息的互操作性。WSDL 提供了服务的描述,以支持开发工具之间的互操作性;它使用交换接口定义的能力补充了通讯互操作性。

一组基本的 Web 服务规范使客户和软件供应商能够解决一些重要的问题。在他们的成功基础上,许多开发人员和公司准备使用 Web 服务技术解决更加困难的问题。Web 服务的巨大成功使得开发人员希望从 Web 服务获得更多的功能。因为一些重要工具和通讯互操作性已经非常成功,所以开发人员现在期望增强互操作的功能。

除了基本的消息互操作性和接口交换之外,开发人员越来越多地要求更高级的应用程序服务能够互操作。许多商业应用程序是在支持像安全和事务这样功能的环境(“中间件”或“操作系统”)中执行的。

人们经常会要求 IBM、Microsoft 和业界其他公司将 Web 服务做得更安全、更可靠而且能够更好地支持事务。另外,也要求我们在提供这些功能的同时,还保持目前 Web 服务中基本的简单性和互操作性。

本文简明扼要地概述了一组满足这些需要的 Web 服务规范。对于规范中的一些细节,我们提供了到实际文档的引用。本文的主要目的是为了简要地定义这些规范为我们的客户提供的价值。还描述了这些规范是如何相互补充,以组成用于分布式应用程序的可靠环境的。

我们面临的一个关键设计挑战是:如何才能够在给予 Web 服务新的安全性、可靠性和事务处理能力的同时又不增加不必要的复杂性呢?

1.1 可组合的服务

正如我们对 SOAPWSDL 所做的那样,IBM、Microsoft 和我们的合作伙伴在定义 Web 服务规范的过程中遵循了可组合性的设计原则。在定义 Web 服务规范的过程中,我们所遵循的方法是以可组合性这一设计原则为基础的。我们制订的每个规范都解决了某个方面的直接需要,而且它本身也是很有价值的。例如,开发人员可以采用可靠的消息处理来简化他们的解决方案开发,也可以采用 BPEL4WS 来定义他们的服务组合。此外,在保持每个规范独立的同时,也可以将它们组合起来设计,使它们彼此协同工作。

我们使用可组合性一词来描述那些可以进行组合,以提供更强大功能的独立规范。操作系统和中间件提供商可以支持组合的功能,例如,这些供应商可以集成可靠的消息处理支持,用于与 BPEL4WS 进程进行通讯。这个示例组合了两个独立的规范,通过消除进程设计过程中处理消息通讯错误的需要,从而简化了通讯进程的开发。

可组合性使得新概念、工具和服务的逐渐增加使用循序渐进发现成为可能。开发人员只需学习和实现一些必要的东西,而无需进行任何其他操作。解决方案的复杂性只会因问题需求的增加而增加,而不会因为技术“膨胀”而增加。

可组合性已经并将继续是 Web 服务的主要设计目标之一。在过去几年中,我们定义了最基本的 Web 服务规范(SOAP 和 WSDL),以便这些规范本身就支持组合。Web 服务的基本特征之一是规则的、多部分的消息结构。这种结构使新功能的组合成为可能。支持新服务的新消息元素可以以一种不改变现有功能处理的方式添加到消息中。例如,可以单独添加事务处理标识符和可靠消息处理序列号。这两个扩展不会彼此冲突,并且与预先存在的消息结构相兼容。

单击此处查看大图像

1. 可组合性允许根据需要使用元素

图 1 显示了一个简单的 Web 服务消息,它包含了用于 WS-Addressing WS-SecurityWS-ReliableMessaging的元素。请注意,这些 WS-Addressing、WS-Security 和 WS-ReliableMessaging 元素是独立的,并且这些元素可以单独使用而不会改变其他元素的处理。

这种特征使得安全性、可靠性和事务能够根据可组合的消息元素进行定义。

组合的概念还允许创建一组特定的定义完善的可组合 Web 服务来支持安全性、可靠性等等。这些定义完善的服务指定支持更高级 Web 服务功能所需的服务行为。在 WS-Trust中定义的安全性令牌服务 (Secure Token Service) 就是这样的一个例子,它签发和验证消息中的安全性元素。

此外,让服务使用者能够决定受支持和所需的服务保证是非常重要的。服务必须描述它们对于事务、安全性、可靠消息处理等的要求和支持。WS-Policy 使得 Web 服务能够逐渐增强它们的 WSDL,以描述它们支持或需要哪些事务、安全性和可靠性功能。WSDL 和 WS-Policy使得组合服务描述成为可能。而这又使得其他方能够了解与服务交互时,需要使用什么消息元素和更高级的服务。

1.2 实践中的组合示例

图 2 简单显示了实践中的组合。其中的客户和提供商使用 Web 服务来处理订单。

单击此处查看大图像

2. 订单处理系统中的组合

在构建这些 Web 服务的过程中,开发人员使用 WSDL 和相关的文档来描述它们的业务接口。这些 WSDL 文档描述了客户 Web 服务和提供商 Web 服务将处理的一组消息,例如从客户传递到提供商的 SubmitPurchaseOrder (SubmitPO) 消息。如图 2 上部所示。一旦应用程序的核心部分就位之后,开发人员就可以决定支持附加功能了。例如在这里,他们决定将订单处理事务化。为达到此目的,他们将下列元素组合到了现有结构中:

  • 服务将描述它们对事务支持的 WS-Policy 文档,与它们服务的 WSDL 描述相关联。请注意,虽然这些策略声明增强了,但是并没有从根本上改变现有的业务功能。

  • 为了支持事务处理,服务添加了一个附加的消息元素来描述组合在一起的事务,而没有从根本上改变现有的应用程序消息。

  • 当提供商服务收到包含事务元素的消息时,它使用此信息与一个称为协调器的指定 Web 服务进行通讯,该服务支持事务处理功能。另外,这个附加的 Web 服务只添加到解决方案,而不需要修改现有业务功能的描述。

  • 最后,服务可以实现附加的操作来支持与事务协调器服务的集成。

在前面的图中,突出显示了这些附加的元素。

该模型是递增的和可组合的,因为:

  • 添加新的功能可独立于添加其他功能而完成。

  • 添加功能并没有干扰现有的消息、消息处理逻辑或 WSDL。

可组合性是一个越来越重要的设计原则,不过这种方法并不总是非常好理解。各个 Web 服务规范定义了各个元素和服务如何进行互操作,而本白皮书旨在概述如何能够组合一些规范以提供更复杂的可互操作 Web 服务。

2.0 Web 服务:面向服务的结构

在最近几年中,我们目睹了一系列以 Web 服务开发为中心的活动。对于所有这样的活动,有必要回过头来问一问“为什么”。当然,Web 服务并不会提供新种类的计算能力 - 毕竟,所有 Web 服务仍然运行在现有的计算机上,执行相同的指令集,并且访问相同的数据。而且在许多情况下,Web 服务协议实际上可能会增加某个特定任务的协议开销。

我们之所以如此看重 Web 服务的主要原因之一在于,Web 服务非常适于启用面向服务的结构 (Service-Oriented Architecture, SOA)。使用 Web 服务构建 SOA 时,解决方案由一些自治服务组成,这些自治服务通过 URL 进行标识,带有使用 WSDL 描述并处理定义完善的 XML 消息的接口。SOA 是对实现解决方案的面向对象 (OO)、过程性和以数据为中心的方法的自然补充。实际上,在创建 SOA 系统时,各个服务通常是使用这些技术中的一个或多个进行构造的。

面向服务的结构不同于面向对象和过程性系统的一个关键方面是:绑定。服务根据它们提供什么功能和它们如何提供这些功能来进行交互。而面向对象和过程性系统则根据类型或名称将元素链接在一起。以下几节将更详细地对此进行讨论。

2.1 服务是通过架构和协定而不是类型描述的

与以前的系统不同,Web 服务模型不是基于需要公共实现的共享类型概念运行的。相反,服务的交互完全是基于协定(用于消息处理行为的 WSDL/BPEL4WS)和架构(用于消息结构的 WSDL/XSD)的。这使得服务能够描述它可以发送和/或接收的消息的结构以及对这些消息的顺序约束。结构和行为之间的分离以及对这些特征的显式和机器可验证的描述,简化了异类环境中的集成。

此外,这种信息充分地描述了服务接口的特征,从而使得应用程序集成不需要共享的执行环境就能够创建消息结构或行为。

面向服务的模型采用一个完全分布式的环境,在这种环境中,将架构和/或协定中的更改传递到曾经遇到服务的所有各方是非常困难的(如果不是不可能的话)。面向服务意味着架构和协定应该保持向后兼容,并且可以包含特定处理系统不完全理解的信息。

因此,为了在面向服务设计中使用而设计的协定和架构技术,比传统的面向对象的接口更具灵活性。特别是,服务以不破坏已部署应用程序的方式使用了一些功能来改进服务,这些功能例如 XML 元素通配符(如 xsd:any)、架构扩展和可选的 SOAP 标头。这些特征是 Web 服务的可组合性的关键。

2.2 服务兼容性多于类型兼容性

过程性设计和面向对象设计通常会将类型兼容性与语义兼容性等同起来。面向服务为决定兼容性提供了更加丰富的模型。结构兼容性是基于协定(WSDL 和可选的 BPEL4WS)和架构 (XSD) 的,并且可以进行验证。此外,WS-Policy 的出现提供了对于服务之间服务保证兼容性的附加自动分析。这是根据功能和需求的显式断言,以 WS-Policy 声明的形式来完成的。

使用 WS-Policy,服务可以以一种计算机可读的、包含断言组合的策略表达式形式,来描述它们的服务保证能力和需求。这就使得服务能够根据它们“如何”或“以什么样的质量”提供它们的协定来相互选择。

策略断言是通过稳定的且全局唯一的名称来标识的,不管断言应用到哪个服务,这种名称的含义在时间和空间上都是一致的。策略断言也可以带有限定断言确切解释的参数。

2.3 面向服务假定坏事情可能并且必将发生

以前的一些用于分布式应用程序的方法显式地假定了一个通用的类型空间、执行模型和过程/对象引用模型。其实,“内存中”编程模型定义了这个分布式系统模型。

面向服务仅假定服务自治执行,而没有本地执行或通用操作环境的观念。因此,SOA 显式地假定通讯、可用性和类型错误都是常见的。

为了维护系统的完整性,面向服务的设计显式地依赖于各种技术来处理异步模式和部分失败模式。像异步消息处理、事务、可靠消息处理和冗余部署这样的技术都是面向服务系统中的标准内容。

此外,与内存中模型不同的是,面向服务不但会假定传入消息可能存在格式错误,而且还会假定它可能是出于恶意或完全非预期的目的进行传递的。因此,面向服务系统是通过要求应用程序来证明已经将所需的权限授予了发送方,从而在所有消息发送方上增加证明工作来保护自己的。与服务自治的概念一致,面向服务结构在管理上通常依赖于托管信任关系,来避免典型 Web 应用程序中常见的每服务验证机制。

2.4 面向服务支持服务的灵活绑定

面向服务的结构 (SOA) 的一个核心概念就是服务的灵活绑定。更传统的过程性模型、组件模型和对象模型通过引用(指针)或名称来绑定组件。SOA 则支持更动态地发现服务实例,来提供请求者所期望的接口、语义和服务保证。

在过程性系统或面向对象的系统中,调用方一般根据它导出的类型或共享命名空间来查找服务器。而在 SOA 系统中,调用方可以搜索注册中心(例如 UDDI),来查找符合下面条件的服务。

  • 1. 这是与调用方的需求相兼容的消息。兼容性可以通过 WSDL,或者与大家熟知的 XML 架构中的消息匹配来实现。

  • 2. 调用者所需的服务保证的文档支持。例如,调用者可能需要获得安全性或事务的方法。

有关服务实现的这种松散绑定,使得行为的其他备用实现成为可能,可以用于解决各种各样的业务需求。例如,这种备用实现可对应于供应链中的备用供应商,从而能够在发生市场条件变化情况下更快地作出响应。同样,这种备用实现可以是地理上分散的数据中心,从而能够在灾难出现时起作用。

3.0 Web 服务规范和功能

此节内容将概述 Web 服务规范。

3.1 Web 服务的可组合方法

此节将简要地描述可用的 Web 服务规范。我们将阐述它们对解决方案提供商的价值、它们在更广泛结构中的角色、以及它们是如何互为补充的。

下图提供了由 IBM、Microsoft 和其他公司发布的 Web 服务规范的高级分组。请注意,该图的意图并不在于暗示组与组之间严格的分层;它的目的在于直观地说明各个功能区之间的关系。例如,消息安全性不需要描述 (Description),而同样的描述对于消息处理 (Messaging) 来说则是一个有用的开发时概念。

单击此处查看大图像

3. 可互操作的 Web 服务协议结构

3.2 基础 传输和消息处理

如果我发给您一封用法语写的信,而您希望看到的却是一个用英语进行电话交谈,那么我们将无法沟通。Web 服务的互操作性面临着同样的问题;我们通过提供一组通用的传输和消息处理技术来解决这个问题。

另外,为了确保这些技术在实践中是有效的,IBM、Microsoft 和其他公司创立了 Web 服务互操作性组织 (Web Services Interoperability Organization,WS-I)。最近,WS-I 发布了一个基本概要,正式记录了可互操作的 Web 服务传输和消息处理机制。

3.2.1 传输 — HTTP HTTP/S SMTP

这一组规范定义了用于在 Web 服务之间移动原始数据的核心通讯机制。

例如,这个规范组中包括的 HTTP、HTTP/S 和简单邮件传输协议 (SMTP)。Web 服务实现可能还支持其他的传输,但是提供对于标准的、可互操作协议的支持是非常重要的。

3.2.2 消息格式 — XSD

下一组规范为编码用于传输的 Web 服务消息定义了可互操作的机制。这些传输会在服务之间移动“字节”块。只有当各个参与方能够将字节转换成它们的应用程序可以处理的有用数据结构时,这才是有用的。

消息处理规范组定义了如何正确地设置消息的格式。XML 和 XML 架构定义提供了抽象统一消息(数据)结构的机制。SOAP定义了用于在字节信息中表示 XML 消息的标准编码方法,这里的字节信息是服务通过传输进行交换的。

3.2.3 WS-Addressing

消息和响应都发送到某处和来自于某处。WS-Addressing 提供了一种可互操作的、独立于传输的方法,来标识消息发送方和接收方。 WS-Addressing 还提供了一种更细粒度的方法,来标识发送或者应该接收消息的服务中的特定元素。

现在,大多数使用 Web 服务的系统都会使用放入 HTTP 传输协议中的 URL 为 Web 服务消息的目标进行编码。响应的目标由返回的传输地址确定。这种方法建立在 HTTP 的基本浏览器-服务器模型的基础上。

使用现在的方法,源信息和目标信息都不是消息本身的一部分。这可能会产生几个问题。如果传输连接终止(例如,响应要等很长的时间,然后连接超时)或消息是由中介(如防火墙)转发的,那么该信息就可能会丢失。

WS-Addressing 提供了一种机制,可将目标地址信息、源地址信息和其他重要的地址信息都直接放在 Web 服务消息中。简言之,WS-Addressing 将地址信息从任何特定的传输模型中分离出来。

在许多情况下,消息是直接以服务为目标的,而消息中的地址信息可能是使用 URL 简单描述的。但是在实践中,我们经常会发现,消息的目标是服务中的特定元素或资源。例如,协调服务可能正协调许多任务。协调器需要将大多数传入消息与它管理的特定任务实例相关联,而不是与协调服务本身相关联。

WS-Addressing 为服务所管理的寻址实体提供了一种简单但功能非常强大的机制,称为终结点引用。虽然这样的信息可以用即席的方式在服务的 URL 中进行编码,但是终结点引用提供了一个标准的 XML 元素,从而使得用来编码这种细粒度寻址的结构化方法成为可能。

对寻址进行细粒度的控制加上对消息源和目标进行独立于传输的编码,使得 Web 服务消息能够跨越各种各样的传输通过中介进行发送,并且能够采用异步和扩展的持续时间两种通讯模式。

WS-Addressing 还使发送方能够以一种独立于传输的方式指明响应应该发送到哪里。对消息的响应可以不必发送给发送方。例如,在 HTTP 中,由于没有 WS-Addressing,所以不能指定响应应发送到别处。

这些对消息处理模型的增强使得 Web 服务能够用于支持许多业务方案。例如,某些银行往来任务需要在某些步骤上进行人工复核审批。通常在任何时间点都有许多活动的任务实例。WS-Addressing 提供了一种通用的机制,可将传入或传出消息与特定的任务关联起来。服务使用的这些机制对于那些通过终结点引用使用服务的使用者来说是透明的。

3.3 描述

传输和消息规范允许 Web 服务使用消息进行通讯。但是,各个参与方如何知道这些消息是什么呢?Web 服务如何记录或描述它发送和接收的消息呢?使用 Web 服务需要理解 Web 将使用和将产生的消息 - Web 服务的接口。规范的描述组使 Web 服务能够表达它的接口和功能。

除了消息互操作性之外,这些规范还启用了开发工具互操作性。描述规范提供了一个标准的模型,使得来自不同供应商的各种工具能够协同支持开发人员。就像 Web 服务使得合作伙伴能够从各种实现和基础架构选择中分离出来一样,描述规范则将合作伙伴从开发工具选择中分离出来。

3.3.1 WSDL

Web 服务描述语言 (WSDL)XML 架构 (XSD)> 是这一组中的基础规范。XML 架构使得开发人员和服务提供者能够定义数据结构(例如,采购定单)和消息(例如,CreatePO 消息)的 XML 类型。WSDL 使得 Web 服务能够描述它接收和发送的消息。换句话说,服务根据它接收和发送的消息执行哪些“动作”或“功能”。

WSDL 为各种各样的消息交互模式提供了支持。它支持没有响应的单向输入消息、请求/响应,以及带响应或不带响应的单向发送。后两种模式使服务能够指定它需要的其他服务。

提议的 WSDL 增强功能为服务支持的描述协议和消息格式,以及服务的地址提供支持。

3.3.2 WS-Policy

WSDL 和 XSD 定义提供的信息通常不足以调用 Web 服务。WSDL 和 XSD 定义服务的接口语法,但是它们不会表达关于服务如何提供它的接口或服务期望从调用方得到什么的信息。例如,服务需要安全性或实现事务吗?

WS-Policy 使服务能够指定它期望从调用方那里得到什么和它如何实现其接口。WS-Policy 对于在服务的更高级功能操作上实现互操作性是至关重要的。安全性、事务、可靠消息处理和其他规范需要具体的 WS-Policy 架构。这些内容使得服务能够描述它们期望从调用方得到的或提供给调用方的功能保证。

WS-Policy 框架提供了定义策略表达式的基本模型。

WS-Policy 支持聚合策略声明的语法,并且允许构造更灵活和更完整的策略组。

WS-PolicyAttachment指定了如何使策略组与 XML 消息和 WSDL 元素(操作和 portTypes)相关联。

WS-Policy 和 WS-PolicyAttachment 一起提供了该框架。各个规范定义了特定于它们的域的策略声明和架构。

最后,WS-PolicyAssertions提供了一组基础的通用策略声明,可以用于实现互操作性。

3.3.3 获取描述

XML、XSD、WSDL 和 WS-Policy 支持描述服务的接口和服务保证。但是,服务的潜在用户如何找到这种信息呢?

目前,最常用的方法是通过电子邮件交换或口头表达。为了达到更通用的目的,可伸缩模型是必要的。有两种选择,服务可以直接进入服务以使用 WS-MetadataExchange来获得信息,也可以选择使用 UDDI 服务,该服务聚合了多个目标服务的这种信息。

当开发人员引用服务并且需要了解它做什么时,他们会使用 WS-MetadataExchange。当开发人员想要查找支持一组特定功能的服务的引用时,他们则使用 UDDI。

3.3.4 WS-MetadataExchange

如上所述,服务一般会提供描述该服务本身的信息(如 WSDL、WS-Policy 和 XSD)。我们将与服务有关的信息统称为元数据。WS-MetadataExchange 规范使得服务能够通过 Web 服务接口将元数据提供给其他服务。假定只引用一种 Web服务,潜在用户就可以访问一组 WSDL/SOAP 操作来检索描述该服务的元数据。客户可以在设计时、构建其客户端时或运行时使用 WS-MetadataExchange。

3.3.5 UDDI

通常,收集关于一组服务的元数据,并且使得这些元数据能够以可搜索的方式提供是非常有用的。这样的元数据聚合是一个很有用的存储库,各个机构可以在其中发布其提供的服务,描述其服务的接口,启用服务的特定领域的分类法。 通用描述和发现接口 (UDDI) 规范定义了元数据聚合服务。

解决方案在设计时可以查询 UDDI,以查找与它们的需求相兼容的服务。例如,开发人员可以在定义他们的 BPEL4WS 工作流时使用这些服务。解决方案也可以在运行时查询 UDDI。在这种情况中,调用方“知道”它要求的接口,并且搜索满足其功能要求的服务,或由知名合作伙伴提供的服务。

注意,有一种可用于使用元数据填充 UDDI 服务的机制,它使用 WS-MetadataExchange 从服务中获取元数据。

3.4 服务保证

Web 服务之所以引起人们如此大的热情,在某种程度上是因为它们具有跨接完全不同的系统的能力。开发人员已经使用传输、消息处理和描述的基本功能开发出了许多功能完备的解决方案。然而,为了让开发人员接受用来创建更强大的集成解决方案,Web 服务必须提供一些功能来确保与更传统的中间件解决方案具有相同级别的服务保证。仅仅交换消息是不够的。应用程序和服务驻留在中间件和系统上,这些中间件和系统提供了颇有价值的更高级功能,例如安全性、可靠性和事务处理操作。Web 服务必须为这些功能之间的互操作性提供一种机制。

3.5 安全性

这一规范系列对于跨组织 Web 服务是至关重要的。这些规范支持验证和消息完整性、机密性、信任和隐私。它们也支持不同组织之间的安全联盟。

3.5.1 WS-Security

WS-Security 是安全 Web 服务的基本构造块。现在,大多数分布式 Web 服务依赖于安全性功能的传输级别支持。例如 HTTP/S 验证和 BASIC-Auth 验证。这些安全方法提供了安全通讯的最低必要条件。然而,它们提供的功能级别明显低于现有中间件和分布式环境所提供的功能级别。

下面的两个示例重点讲述了 BASIC-Auth 和 HTTP/S 的缺陷。

  • A 发送消息到服务 B。B 对消息进行部分处理后将其转发到服务 C。HTTP/S 可以提供 A-B 和 B-C 之间的验证、机密性和完整性。然而,C 和 A 不能彼此验证,也不能对 B 隐藏信息。

  • 为了使得 A、B 和 C 使用 BASIC-Auth 进行验证,它们必须共享相同的复制用户和密码信息。在许多情况下,这是不能接受的。

WS-Security 解决了这些问题。它支持:

  • 签名的和加密的安全令牌。A 可以生成一个令牌,C 可以将此令牌作为来自 A 的令牌加以验证。B 不能伪造该令牌。

  • A 可以对选定的元素或整个消息进行签名。这就使得 B 和 C 能够确认该消息自 A 发送它以来没有被更改过。

  • A 可以密封该消息或选定的元素。这确保了只有原本要用于这些元素的服务才可以使用该信息。这就阻止了 B 看到原本用于 C 的信息,同时阻止了 C 会看到原本要用于 B 的信息。

WS-Security 使用现有的安全模型(Kerberos、X509 等等)。这些规范具体地定义了如何以可互操作的方式使用现有的模型。没有 WS-Security,多跃点、多方 Web 服务计算就不可能是安全的。

3.5.2 WS-Trust

安全性依赖于预先定义的信任关系。Kerberos 之所以有效,是因为各个参与方“信任”Kerberos 密钥分发中心。PKI 之所以有效,是因为各个参与方信任根验证机构。WS-Trust定义了建立和验证信任关系的可扩展模型。

WS-Trust 中的密钥概念是安全性令牌服务 (STS)。STS 是一个著名的 Web 服务,它用于签发、交换和验证安全令牌。WS-Trust 允许 Web 服务建立和约定它们“信任”哪些安全性服务器,并且允许它们依赖于这些服务器。

STS 之所以得到了广泛的应用,是因为它可以用于签发安全令牌来作出各种各样的断言。在许多情况下,它将用于签发相同的断言,只是格式不同。例如,STS 可能会签发一个 Kerberos 令牌,断言密钥持有者是 Susan,它也可能会根据受信任的证书机构签发的 X.509 证书来进行这样的断言。这使得使用不同安全技术的组织能够结成联盟。STS 还可能根据一个断言身份声明的传入安全令牌来签发一个安全令牌,断言密钥持有者是 BankTellers 组中的某个成员。

3.5.3 WS-SecureConversation

一些 Web 服务场合只涉及少量消息的简短的偶发性交换。WS-Security 很容易支持这种模型。还有一些情况涉及各种 Web 服务之间持续时间很长的、多消息交换。WS-Security 也支持这种模型,但是解决方案不是最佳的。

在这些情况中,有两种不是最佳的 WS-Security 的用法:

  • 重复使用计算代价昂贵的加密操作,如公钥验证。

  • 使用相同的加密密钥来发送和接收许多消息,提供更多信息以允许强力攻击来“破坏代码”。

因此,像 HTTP/S 这样的协议就使用公钥进行简单的协商,以定义对话专用密钥。这种密钥交换提供了更有效的安全性实现,并且减少了使用一组特定的密钥进行加密的信息量。

WS-SecureConversation对 WS-Security 提供了类似的支持。参与方经常使用带有公钥的 WS-Security 来开始“对话”或“会话”,并且使用 WS-SecureConversation 来约定用于签名和加密信息的会话专用密钥。

3.5.4 WS-Federation

WS-Federation 使得一些组织能够建立一个虚拟的安全域。例如,旅行代理、航空公司和连锁经营旅馆可以建立这样的联盟。“登录”联盟中任一成员的最终用户可以有效地登录所有的成员。WS-Federation 定义了几个模型,用于通过 WS-Trust 和 WS-SecureConversation 拓扑之间的协议来提供联合的安全。

另外,客户在与企业进行交易时常常具有一些“属性”。例如,优先选择靠窗或过道旁的座位或中型汽车。WS-Federation 使得成员能够建立一个联合的属性空间。这就使得每个参与方能够对每个成员有关最终用户的属性信息进行安全控制的访问。

关于个人的属性和信息可能会由于私密性保护,或者因为这些信息为特定成员提供了竞争优势而进行秘密存放。为了支持这些需求,WS-Federation 支持假名模型。经过旅行代理验证的用户在与航空公司或旅馆交互的过程中,使用代理生成的“别名”。这保护了最终用户的隐私和旅行代理因了解用户属性而可能赢得的竞争优势。

3.6 可靠的消息处理

在 Internet 世界,几乎所有的通讯通道都是不可靠的。消息会丢失。连接会中断。

如果没有可靠的消息处理标准,Web 服务应用程序开发人员就必须将这些功能构建在他们自己的应用程序中。基本方法和技术是很好理解的,例如,许多操作系统和中间件系统都会确保消息具有唯一的标识符,并提供序列号,还在消息丢失时使用重新传输。如果应用程序 Web 服务开发人员在他们的应用程序中实现了这些模型,他们就可能会进行各种不同的假定或设计选择,即使能够达到可靠的消息处理,也几乎不会产生什么应用程序。

3.6.1 WS-ReliableMessaging

WS-ReliableMessaging定义了一些机制,使 Web 服务能够在不可靠的通讯网络上确保消息的传递。

WS-ReliableMessaging 不仅确保了服务可以实现可互操作的方法,而且还通过提供实现协议的服务,使得运行时供应商能够更容易地进行应用程序的开发。这大大简化了应用程序开发的任务。因此,就会大大减少业务逻辑必须处理的错误情况。

最后,业界有很多面向消息的中间件,可以用于可靠地路由和发布消息。每个实现都使用专有的协议。WS-Reliable Messaging 协议使得不同的操作系统和中间件系统能够可靠地交换消息。因而,它支持将两个不同的基础体系结构跨接成一个逻辑上完整的端对端模型。

3.7 事务

复杂的业务情况可能需要多方交换多组消息。例如,几个金融机构提供一种金融产品,涉及保险政策、养老金、支票帐户和经纪帐户。在各个参与方之间交换的多个消息构成了一个逻辑“任务”或“目标”。

为了取得成功,各个参与方必须能够:

  • 启动新的协调的任务。

  • 使操作与它们的逻辑任务相关联。各个参与方可以同时为不同的客户设置多个帐户。

  • 统一计算的结果。例如,每个人都赞同建立的金融产品包吗?

WS-Coordination、WS-AtomicTransaction 和 WS-BusinessActivity 支持这些需求。

3.7.1 WS-Coordination

WS-Coordination 是用于开始和同意多方、多消息 Web 服务任务的结果的通用机制。 WS-Coordination 有三个关键元素:

  • 一个称为协调上下文的消息元素,它会计算过程中在 Web 服务交换的所有消息中进行流动。协调上下文包含对协调服务的 WS-Addressing 终结点引用,而它又包含用于标识正在协调的特定任务的信息。

  • 协调器服务。协调器服务提供一个使用 WSDL 描述的服务,这种服务提供了一些功能,可启动协调的任务,终止协调的任务,允许参与方在任务中注册,以及产生协调上下文,所产生的协调上下文是组内所有消息的一部分。

  • 协调服务还包括一个使用 WSDL 定义的接口,参与的服务使用这个接口来获得协调任务结果的通知。

接收带有新协调上下文的消息的 Web 服务向该上下文中的协调器服务注册,以接收结果信息。其他的规范可以针对域对此框架进行扩充,并确保特定的需求。

WS-Coordination 是一个通用的框架,具有通用的功能。WS-AtomicTransaction 和 WS-BusinessActivity 扩展了此框架,以便使分布式计算中的各个参与方能够很好地决定结果。

3.7.2 WS-AtomicTransaction

WS-AtomicTransaction 定义了一组特定的协议,这组协议可以插入 WS-Coordination 模型,以实现传统的两阶段原子事务处理协议。要注意的一项重要内容是,两阶段模型只是就涉及的服务而言的。提供服务的站点或基础架构可能大肆宣传两阶段提交,但却使用一些其他的企业内部模型,比如补偿模型或版本化模型。这种自由使简单的两阶段提交模型对于长期运行的 Internet 计算来说更有用。

3.7.3 WS-BusinessActivity

WS-BusinessActivity 定义了一组特定的协议,这组协议可以插入 WS-Coordination 模型,以实现长期运行的、基于补偿的事务处理协议。虽然 BPEL4WS 为业务处理定义了一个事务处理模型,但却是 WS-BusinessActivity 指定相应的协议呈现。这又是 Web 服务规范的可组合性的一个例子。

3.8 服务组合

在 Web 服务分层中,最上层的元素是服务组合。服务组合使开发人员能够将交换 SOAP 消息,以及使用 WSDL 和 WS-Policy 定义它们的接口的服务“组合”成聚合的解决方案。该聚合是一个组合的 Web 服务。

3.8.1 BPEL4WS

Web 服务的业务流程执行语言 (BPEL4WS)规范支持服务组合。它使开发人员能够为共同实现一个共享业务解决方案的一组 Web 服务定义结构和行为。这组服务中的每个元素都使用 WSDL 和 WS-Policy 定义自己的接口。这个组合解决方案本身就是一个 Web 服务,它支持 HTTP/SOAP 消息并且使用 WSDL 和 WS-Policy 定义其接口。

组合有三个方面:结构、信息行为。BPEL4WS 引入了三种结构来支持每个组合方面。

partnerLink 定义了参与整个解决方案的 Web 服务和组合服务之间的命名关联。组合服务和参与服务使用 WSDL 和 WS-Policy 定义了它们彼此之间的接口。制造企业和供应商之间的关联可能就是一个例子。

组合服务和合作伙伴之间的 partnerLink 概念和 WSDL/WS-Policy 接口定义了服务组合的结构。它们定义协作构成组合的服务类型、以及它们使用何种级别的保证(安全性、事务等等)交换哪些信息。

BPEL4WS 还为定义服务组合的信息提供了支持。BPEL4WS 定义了变量的概念。组合服务定义了一组变量,其中的每个变量都有一个 XSD 定义。特定服务的当前状态就是其变量的状态。这定义了它已经接收或发送了哪些消息。

最后,BPEL4WS 通过活动的概念支持对于组合服务行为的定义。BPEL4WS 将服务定义为一组活动或“步骤”,这些活动和步骤定义了该服务的行为。最基本的活动是将消息发送给合作方伙伴,或从合作伙伴那里接收消息。每个消息都对应一个变量。BPEL4WS 为在变量之间移动数据提供了支持。

BPEL4WS 活动的一个关键方面是,通过允许控制使用不确定的行为,BPEL4WS 为定义服务外部可见的(公共)的行为提供了特殊支持。例如这样的情况,在接受采购订单 (PO) 的决策流程中,以特定方式进行信用检查可能是供应商的私有事务。BPEL4WS 通过从流程描述中丢弃信用检查行为,允许隐藏这个决策流程,但是会显示采购订单的响应可能是接收还是拒绝。这种类型的抽象流程可以与 WSDL 一起使用,以定义业务合作伙伴之间以及纵向行业领域(如供应链)的可互操作业务协议。

此外,BPEL4WS 还支持几种控制活动的执行流的方法。这些方法包括顺序流和基于图形的流。BPEL4WS 支持变量上的谓词,以确定组合服务遵循哪些控制路径。

总之,BPEL4WS 对以前定义的 Web 服务规范进行了两项补充。

  • BPEL4WS 扩展了用于描述服务的 WSDL 和 WS-Policy 支持。BPEL4WS 支持将 Web 服务组合成聚合服务,描述服务之间的关联,如信息流和行为。这为支持协作设计 Web 服务的更高层工具之间的互操作性提供了支持。

  • BPEL4WS 是一种执行语言。BPEL4WS 允许开发人员完全指定一个组合 Web 服务的行为。IBM、Microsoft 和其他合作伙伴将提供环境,来执行 BPEL4WS 文档和支持合作伙伴的设计时和执行时绑定。

4.0 实践中的 Web 服务 一个示例

下面的方案显示了可以如何组合使用这些 WS 规范,以创建能够解决真实世界中的需求的 Web 服务。该方案提供了一个由于不同的 WS 规范的可组合性为开发人员带来强大功能的示例。

这个方案中描述的 Web 服务是为 2003 年 9 月 17 日 IBM-Microsoft 联合举行的技术演示会而准备的。当时使用这些 Web 服务创建了一个可互操作的、安全的、可靠的、事务化的应用程序,而且该应用程序跨越了组织的边界。

这个示例演示了一个联合订单处理和供应商管理库存 (VMI) 系统,这个系统用于汽车零售商从汽车制造商那里订购零件;而汽车制造商又从运行着多个仓库的供应商那里获得零件。该系统中,所有应用程序到应用程序的通讯都无一例外地是使用前面描述的 Web 服务协议构建的,并且运行在使用 IBM 和 Microsoft 软件的一组计算机上。

该方案涉及了经营企业的一些最常见方面的内容 - 在零售企业、零售企业的批发商以及批发商的供应商之间进行的交互。该方案说明了各种不同的 WS 规范如何能够组成自动的业务流程基本要素,如:

4.1 第一部分:客户体验

该示例是从 Heather 登录她的零售商店的内部网 web 站点开始的,Heather 是一个名为 Auto Dealer 的公司的雇员。这个 web 站点是使用标准、现有的 web 技术构建的。Heather 通过她的浏览器进入该站点。对该站点的访问是受密码保护的。

单击此处查看大图像

4. Heather 登录她公司的安全内部网 Web 站点,并且导航到她自定义的 My Page

Heather 单击 My Page。在后台,应用程序会从 Auto Dealer(汽车零售商)的库存数据库中收集信息。如果某一商品的库存级别降到了定义的阈值以下,就生成一份报告,并且将其列在 Heather 页面的 "Your Alerts" 显示内容中。

Heather 看见她公司的 WindshieldPro 刮水器的库存不足。

Heather 单击该链接,然后无缝地转到 Auto Manufacturer(汽车制造商)外部网上的安全 Web 页面中,在那里 Heather 可以下达订单。这种体验是无缝的,因为 Auto Dealer 的软件是基于 Web 服务的。链接 Auto Dealer 的内部网与 Auto Manufacturer 外部网的 Web 服务是通过 WS-Federation 组合起来的。WS-Federation 确保一个站点授予的安全性凭据能够得到第二个站点的认可。

下面是它的工作流程。Auto Dealer 与 Auto Manufacturer 已经同意联合它们的站点。WS-Federation 会协调一系列服务器到服务器的通讯。只要 Heather 单击 WindshieldPro 链接进入 Auto Manufacturer 的 Web 页面,Auto Manufacturer 的 Web 页面服务器就会查询它的授权服务,然后这个授权服务再查询 Auto Dealer 的授权服务。Auto Dealer 的授权服务确认 Heather 是一个授权的用户,随后将凭据以及 Heather 的零售商店的名称发回到了 Auto Manufacturer 的授权服务,再由这个授权服务授予 Heather 访问权限。上述过程完全是无缝地发生的,而 Heather 所注意到的只是她已经从一个 Web 页进入了另一个 Web 页。

此外,该 Web 服务还会查询 Auto Manufacturer 的客户数据库,以查找与 Heather 的帐户有关的订购信息。此信息显示在 Auto Manufacturer Web 页面的个性化 "My Page" 上。

单击此处查看大图像

5. 通过 WS-Federated 组合的 Web 服务使 Heather 能够无缝地从她在 Auto Dealer 上的个性化页面转到她在 Auto Manufacture 的个性化页面。

利用其在 Auto Manufacturer 外部网上的个性化 Web 页面, Heather 可以查看目前是否有未完成的订单;她有一个订单(订购 50 个 SuperTires)正在发送中;她的已完成订单列表包括 20 个 CDPlus 和 50 个 Leather Cleaner。

Heather 单击 "Create New Order",从而打开一个新的页面,预先填充了她需要的零件 - WindshieldPro 牌刮水器和订购日期。她只需输入数量就可以了。完成订单所需的其他全部信息都是从 Auto Manufacturer 的数据库中填充的。

单击此处查看大图像

6. 因为许多订单数据已经从 Auto Manufacturer 客户数据库上 Heather 的文件中导入了,所以下订单的过程非常简单。

Heather 提交订单后,要么搜索需要购买的其他零件,要么单击 Logout 结束她的会话,以阻止其他人在她不在时使用她的计算机中下达订单。

注意,通过 WS-Federation 组合 Web 服务降低了 Auto Dealer 和 Auto Manufacturer 的管理成本,并且为它们提供了端到端的安全性。如果没有这项技术,Auto Manufacturer 将不得不维护一个所有授权的零售商店雇员及其密码的列表。而这样做的成本将非常高昂且容易出错,同时还降低了应用程序的安全性。

举例来说,如果 Heather 辞职了,她的用户帐户就会从 Auto Dealer 删除。但是,如果零售商店的管理员忘记通知 Auto Manufacturer 有关 Heather 的离职,Heather 就可以继续访问这个购买站点。而使用 WS-Federation,这将不是一个问题,因为唯一必须更改的系统是 Auto Dealer 的 Identity Provider(身份提供程序)服务。Auto Manufacture 的系统(包括应用程序和授权服务)原来就不知道 Heather,她的用户名或她的密码。

4.2 第二部分:供应商体验

虽然 Heather 从 Auto Manufacture 订购 WindshieldPro 牌刮水器,但实际该公司制造自己的刮水器已经是半个世纪以前的事了。WindshieldPro 牌刮水器来自一个供应商 Supplier。

Tony 是 Supplier 的销售代表,就像 Heather 登录到 Auto Dealer 的内部网上一样,他也登录 Supplier 的内部网来开始他一天的工作。不过,Tony 没有使用标准的 Web 浏览器,他使用的是具有内置的 Web 服务支持的 Windows 应用程序。

单击此处查看大图像

7. Supplier 内部网上 Tony 的个人页面提醒他检查他的一个主要客户 Auto Manufacturer 的订单和库存。

当 Tony 单击检查订单和库存时,他的应用程序使用 Web 服务来请求允许 Tony 访问的库存数据。

这个应用程序级 Web 服务数据请求的一种关键方面是,它与 WS-Federation 组合在一起,而该 WS-Federation 验证他对 Auto Manufacturer 的外部网的访问权限。

该 Web 服务把结果返回到 Supplier 的页面,在该页面上,将按照产品类型和当前库存数量显示结果。

单击此处查看大图像

8. Web 服务使用 Auto Manufacturer 的库存数据库中的库存数据填充 Tony Supplier 页面。通过将其与 WS-Security WS-Federation 进行组合,对这个请求进行了安全保护。

Supplier 已经与 Auto Manufacturer 达成了即时 (just-in-time) 购买协议。Tony 获得了这样的授权,一旦库存降到 20 以下,就可以代表 Auto Manufacturer 作为供应商管理库存 (Vendor Managed Inventory,VMI) 的一部分提供自动的再供应订单。Tony 单击 WindshieldPro 来下达订单。在 Tony 和 Auto Manufacturer 之间传递的所有消息是受保护的,因为该应用程序由与 WS-Security 的保护组合在一起的 Web 服务的支持。

单击此处查看大图像

9. Auto Manufacturer 达成的即时协议允许 Tony 代表该公司输入订单。

Tony 的应用程序为他提供了一个屏幕,可以在其中使用 Auto Manufacturer 的采购订单来创建对 Supplier 的请求。Tony 订购了 50个 WindishieldPros 牌刮水器,这些刮水器将直接发货到 Auto Manufacturer。

当 Tony 单击 OK 时,Warehouse Service(仓库服务,一个与 WS-AtomicTransactions、WS-Security 和 WS-ReliableMessaging 组合在一起的 Web 服务)就尝试使用另一个 Web 服务(Warehouse Service 的下级服务)下达订单。如果响应没有立即从 Warehouse Service 返回(因为临时网络繁忙),WS-ReliableMessaging 就会继续重新发送该查询,直到收到一个响应为止。

当 Warehouse Service 接收到订单时,它就将该订单内部转发到该公司的两个物理仓库。由于这涉及到两个仓库之间的数据库,所以可以使用 WS-AtomicTransaction 来确保数据库之间的事务处理行为。

仓库应用程序将订单在下级 Warehouse Service 中进行分配,以确保库存量,将订单的 70% 发往仓库1 (Warehouse 1),剩下的 30% 发往仓库 2 (Warehouse 2)。主仓库 (Main Warehouse) 中的根协调器 (Root Coordinator) 发送一个消息到仓库 2 的根协调器,请求订单的30%。仓库 2 的根协调器检查它的库存,然后发送一个消息到主仓库中的根协调器,告知没有足够的存货。

主仓库中的根协调器知道没有足够的库存,就取消了整个事务,然后发送消息到 Tony 的 Web 服务应用程序,表明了库存状态、库存级别以及该事务已经取消。根协调器开始回滚事务,并且在完成时返回到该仓库,通知它事务已经被取消。

Tony 知道当前的库存后,就发送了另一个请求到仓库。根协调器在其他的事务性实体(其他事务的控制器)中协调,并且将这个请求发送到了 2 个仓库,过程与前面的过程相同。由于我们使用 WS-Security 对整个消息主体进行签名,这样无论在哪个域中,您都会知道您是安全的。

现在,根协调器提交事务,锁定资源,然后完成事务。消息发送回到 Tony,表明事务已经成功完成。

在这些消息中,WS-AtomicTransaction 与 WS-ReliableMessaging 和 WS-Security 组合在一起,提供了一个完整、可运用于企业的分布式系统。

5.0 结束语

IBM、Microsoft 和我们的合作伙伴正在开发 Web 服务规范,这些规范可以用作构建新一代强大、安全、可靠、事务化 Web 服务的构造块。

这些规范是按照模块化和可组合的方式进行设计的,因此开发人员可以利用他们所需要的功能。这种“组件似的”可组合性将使开发人员能够以简单而灵活的方式创建功能强大的 Web 服务,同时仅产生由于特定的应用程序而引起的复杂性级别。

这些技术使组织能够更容易地使用面向服务结构 (SOA) 来创建应用程序。此外,IBM 和 Microsoft 已经演示了安全、可靠、事务化的 SOA 应用程序,举例说明了可以使用此方法创建的许多业务流程。而且,这些演示是在一组异类系统(由 IBM WebSphere 和 Microsoft .NET 软件组成)上的联合安全性环境中进行的。

我们期望这些 Web 服务技术能够在各种操作系统、中间件中使用,并且会出现能够使开发人员更加容易使用这些技术的工具。随着开发人员和组织使用这些系统来创建下一代基于 Web 服务的解决方案,我们将会欣喜地看到一些新兴的应用程序。


 
posted on 2009-03-10 00:48  antony.net  阅读(2146)  评论(0编辑  收藏  举报