日期:2009-04-03  浏览次数:21188 次

一、Web服务安全与WS-Security

  毫无疑问,SOAP和XML Web服务在交互操作和标准上已经完全改变了电子商务领域的格局。

  然而直到最近,在Web服务技术领域仍然存在着一些缺陷,那就是处理消息级别的安全、认证、加密、数字签名、路由和附件等问题的能力。为了解决这些安全问题,像IBM、Microsoft和Verisign这样的公司和组织正牵头合作制定统一的Web服务安全规范,以便利用它们原有的Web服务交互操作概念和商业模型,他们推出了WS-Security等规范。可以这么说,自从SOAP规范形成以后,WS-Security规范及其后续的工作可能是Web服务技术领域的一次最重要的进步。

  随着WS-Security规范的定稿,各大软件厂商开始认真地考虑为其产品提供使用相同Web服务安全语言的接口和编程工具箱,Web服务开发者也将能够使用这些厂商提供的工具加强他们所开发的Web服务的安全性。

  二、WSE安全性能简介

  Microsoft推出了Web Services Enhancements 1.0 for .NET(以下简称WSE),它是一个类库,用于实现高级 Web 服务协议,这也是该公司的第一个使用WS-Security等规范实现SOAP消息安全的工具套件。

  保护Web服务安全的一个很重要的环节就是保护其SOAP消息传递的安全。

  使用WSE后,SOAP消息可以自己验证其完整性,并可使用定义在WS-Security规范中的机制加密。

  WSE1.0支持的所有WS-Security特性都是通过实现SecurityInputFilter和 SecurityOutputFilter对象的安全性输入输出过滤器实现的,它支持的安全特性有:

  1. 数字签名

  2. 加密

  3. 使用用户名令牌签名并加密

  4. 使用X.509证书签名并加密

  5. 使用自定义二进制令牌签名并加密

  WSE1.0不支持Security Assertion Markup Language(SAML,安全声明标注语言),但Microsoft公司正积极在其.NET Server中实现SAML体系结构。当然,开发者自己可以自由的实现SAML。唯一的不足是还不能使用WSDL描述遵循WS-Security规范的Web服务的WS-Security接口。

  WSE的体系结构模型基于处理入站和出站SOAP消息的过滤器管道。它是建立在已有的SOAPExtension类的基础上的,有使用过SOAPExtension类行进压缩、加密、记录和其它操作经验的开发者会发现他们对WSE其实很熟悉。

  WSE提供了一个Microsoft.Web.Services.SoapContext类,让我们可以处理WS-Security SOAP头和其它入站的SOAP消息头,同时可为出站的SOAP消息添加WS-Security头。WSE还有一个包装类为SOAP请求和响应添加SOAPContext(与HttpContext类似),同时服务器使用一个SOAPExtension类“Microsoft.Web.Services.WebServicesExtension”,让我们可以验证入站的SOAP消息,还提供了我们可从我们的WebMethod中访问的请求和响应SoapContext。

  学习使用WSE最大的障碍在于有时很难理解Microsoft的技术文档和相关文章,即使对于那些有丰富经验的高级开发人员来说也是如此,并且关于这方面的文章很少。在本文中,我将给出一个简单的例子,介绍如何使用WSE实现基本的用户名令牌的验证过程,以保证Web服务的安全。

  三、设置WSE环境

  为了设置基本的WSE环境,我们需要配置ASP.NET应用程序,使其能够使用WSE SOAPExtension。最简单的方法是把所需的/configuration/system.web/webServices/soapExtensionTypes/Add元素添加到你的Web服务虚拟目录中的web.config里,如下所示:

<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>

  注意type属性必须写在一行中,但是在文中考虑到篇幅的问题需要把它分为几行,所以请读者多加注意。而且要注意,在开始使用WSE之前,我们必须在工程中加入对Microsoft.Web.Services.dll的引用。
  四、基本的用户名令牌认证

  在我们数字签名SOAP消息之前,必须先弄清楚谁正在签名。因此,我们将探讨一下用户名令牌(UsernameToken)的概念,同时了解WSE如何允许我们验证用户名令牌。

  为了在Web服务中使用WSE验证用户名/密码,我们需要知道WSE在这方面为我们提供了什么?WS-Security定义了一个UsernameToken元素,它提供了基本用户名/密码验证的方法。如果你有使用HTTP的经验,那么你会发现UsernameToken与Basic Authentication非常类似。有三种用户名令牌,但是通常情况下我们只对最后两种最感兴趣:

<!--明文密码-->
<UsernameToken>
<Username>user1</Username>
<Password Type="wsse:PasswordText">suangywang</Password>
</UsernameToken>

  这种方法使用明文密码。我们不难想象,在服务器上将进行核对数据库,验证用户名与密码,看是否有匹配的用户名/密码对这一系列验证操作。

<!--密码摘要-->
<UsernameToken>
<Username>user1</Username>
<Password Type="wsse:PasswordDigest">
QSMAKo67+vzYnU9TcMSqOFXy14U=
</Password>
</UsernameToken>

  这种方法发送一个密码摘要(digest)代替明文密码。使用密码摘要,密码就不会通过网络发送,这样黑客就不太可能算出Web服务的密码。密码摘要是用散列函数计算的。这个过程只是单向的,意味着将函数反向并找到对应于摘要的消息是不可能的,因为该过程以这样一种方式实现,所以找到散列到同一摘要的两条不同密码在计算上难以实现。但是黑客可以发送散列密码,然后冒充原始发送人被验证。为了避免这个问题,Web Services Security Addendum(Web服务安全补遗)已经增加一个辅助的保护措施。补遗中规定必须发送密码的摘要版本,而不仅仅发送散列密码。这个摘要信息包含一个密码散列,标识请求的唯一的Nonce和创建时间。因此绝对不会出现相同的两个密码散列。如下所示是修正后的用户名令牌UsernameToken。

<!--修正后的用户名令牌-->
<wsse:UsernameToken
xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"
wsu:Id="SecurityToken-59845323-5dcb-4a6b-a7fb-94a0d