在.NET中建立Web service安全措施

 到目前为止安全性是开发和部署Web service的最基本的内容之一。有很多的论文、文档以及示例说明怎样保护Web service,但是这些信息中的绝大多数所涉及到的都是些有关理论和实践的高级、抽象的定义,很少人提及其具体实现。

在这个三部系列的第一部分,我们将通过一个使用定制的SOAP HEADER的例子来讨论一些有关具体编程的Web service安全性。示例Web service将使用cookie去获取用户的安全环境(context),从而在方法间维护状态,Web service消费者将使用一个Windows应用程序来实现。

一个可重用安全模式
典型的Web service一般是作为一个ASP.NET应用的附加功能或者API而存在的。Web service既可以直接地与数据库交互,也可以在一个N层解决方案中通过调用中间件来完成其功能。在应用程序中Web service需要知道是谁调用了它以及那个用户具有什么样的特权。

多数情况下,用户、角色、商业规则以及授权是已经实现了的,你只要简单地提取这些信息。Web service需要实现一个模式以确定请求客户的信任凭证。理论上在Web service中可以传递用户ID和密码给每个方法,但是一个更面向对象的方法是创建一个继承System.Web.Services.Protocols.SoapHeader的类。这个类将成为我们的SOAP Header,它将被传递到Web service,其中包含我们用来验证用户的所有信息。

服务器实现

 

 

 

 

 

 


服务器实现
下面的列表1给出了一个简单Web service的服务器端实现代码,SecureWebServiceTester.asmx,以及相关的SOAP Header类:

列表1


 Imports System.Web.Services
 Imports System.Web.Security
 Imports System.Web.Services.Protocols
 
 Public Class SecurityContext
     Inherits SoapHeader
 
     Public userId As String
     Public password As String
 End Class
 
 <WebService(Namespace:="http://tempuri.org/")> _
 Public Class SecureWebServiceTester
     Inherits System.Web.Services.WebService
 
     Public secureCtx As SecurityContext
 
     <WebMethod()> Public Function HelloWorld() As String
         If Context.User.Identity.IsAuthenticated = True Then
             HelloWorld = "Hello World"
 
         Else
             HelloWorld = "Invalid User"
         End If
 
     End Function
 
     <WebMethod(), SoapHeader("secureCtx", Required:=True, _
     Direction:=SoapHeaderDirection.InOut)> _
     Public Function LoginUser() As Boolean
 
         If secureCtx Is Nothing Then Return False
 
         If secureCtx.userId = "John" And secureCtx.password = "Doe" _
         Then
             FormsAuthentication.SetAuthCookie(secureCtx.userId, True)
             Return True
         Else
             Return False
         End If
 
     End Function
 
 End Class
SercurityContext类扩展了SoapHeader类,它告诉.NET Framework它是一个Soap Header并且允许在<WebMethod()>属性中被参考。主类SecureWebServicesTester包含了Web services的实际实现了的方法,这些方法由<WebMethod()>属性标示。

LoginUser()函数接受我们的SecureContext Soap Header类的一个实例,它像使用其他对象一样使用这个传入的对象。注意对象名字在引号中被参考的,并且与secureCtx类属性匹配。

然后这个方法就通过检查usrId和secureCtx对象中的密码变量来完成验证。如果LoginUser()方法确认用户是合法的,它就产生一个验证单据,并将其插入响应的cookie集合中。

HelloWorld()方法是一个一旦客户端得到验证以后你可以在Web service中调用的一个很普通的方法。这个模式需要较少的代码,因为在一个session中只需进行一次授权,然后就可以简单地将Web service实现逻辑包装起来。

If Context.User.Identity.IsAuthenticated = True Then...
客户端实现


客户端实现
现在Web service已经实现并且可以运行,我们需要编写Web service消费者。这个模式的不足之处是客户端必须启用cookie以维护安全单据。典型的客户端一般都是一个Web浏览器,明显地它提供内建cookie处理功能,如果用户没有禁用它。但是如果客户端是一个桌面Windows应用程序,那么如何去访问Web service呢?列表2的示例代码给出了如何从Windows应用程序中消费Web service。

列表2


Imports System.Net.CookieContainer
    
     Public Class Form1
         Inherits System.Windows.Forms.Form
    
         ' Generate a cookie container object
         Private cookieContainer1 As New System.Net.CookieContainer()
         ' Generate an instance of our Web service
         Private WSObj As New _
         SecureWebServiceTesterProxy.SecureWebServiceTester()
    
     #Region " Windows Form Designer generated code "
         Public Sub New()
             MyBase.New()
    
             'This call is required by      the Windows Form Designer.
             InitializeComponent()
    
             'Add any initialization after      the InitializeComponent() call
             ' Set our Web service's CookieContainer      property to our
             ' cookieContainer1 object
             WSObj.CookieContainer = cookieContainer1
         End Sub
     #End Region
    
         Private Sub btnLogin_Click(ByVal sender As System.Object,      _
         ByVal e As System.EventArgs) Handles btnLogin.Click
             Dim secureCtx As New _
             SecureWebServiceTesterProxy.SecurityContext()
    
             secureCtx.userId = "John"
             secureCtx.password = "Doe"
    
             wsobj.SecurityContextValue      = secureCtx
    
             Me.lblReturnMsg.Text = "LoginUser      returned: " + _
             WSObj.LoginUser().ToString
         End Sub
    
         Private Sub btnHelloWorld_Click(ByVal sender As System.Object,      _
         ByVal e As System.EventArgs) Handles btnHelloWorld.Click
             Me.lblReturnMsg.Text += "HelloWorld      returned: " + _
             WSObj.HelloWorld()
         End Sub
     End Class
要正确的实现我们的Web service,我们必须导入(Import)System.Net.CookieContainer。这样我们就可以创建一个名为CookieContainer1的CookieContainer对象的示例,它存储Web service中LoginUser()方法返回的验证单据。下一步我们将创建Web service自身的一个实例:

Private WSObj As New
 SecureWebServiceTesterProxy.SecureWebServiceTester().
它必须在form一级声明,因为我们的验证单据必须在Windows Form中实现的各种方法间维护状态。至于New()方法,则是由VS.NET产生的,我们将Web service对象的CookieContainer属性设置为cookieContainer1对象。这将告诉Web service对象使用cookie container对象存储由Web service返回的任何cookie。

要从其它的ASP.NET应用中消费Web service,除了手工的Cookie存储代码外,其它部分的代码几乎完全一样。从一个桌面应用程序消费Web service提供了一个强大的功能、灵活性以及可扩展性。

你安全吗?
上面的代码只是一个简单的示例,说明了怎样通过编程拒绝没有合法验证单据的客户端访问Web service来保护你的Web service。在你的安全模型中要求的复杂级别应该由你的商业需求决定。如果应用程序中数据的敏感度比较高,那么就应该有一个测量尺度来保证你的消费者的数据尽量安全、秘密。

当然并不是所有的应用程序都需要上面的安全模式,尤其是在你的Web service可以自由使用的时候。但是其它的应用程序就需要严格安全尺度,他们的卖点就是其安全级别。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值