監(jiān)理公司管理系統(tǒng) | 工程企業(yè)管理系統(tǒng) | OA系統(tǒng) | ERP系統(tǒng) | 造價(jià)咨詢管理系統(tǒng) | 工程設(shè)計(jì)管理系統(tǒng) | 甲方項(xiàng)目管理系統(tǒng) | 簽約案例 | 客戶案例 | 在線試用
X 關(guān)閉

在.NET中建立Web service安全措施(第一部分)

申請(qǐng)免費(fèi)試用、咨詢電話:400-8352-114

AMTeam.org

在.NET中建立Web service安全措施(第一部分)

到目前為止安全性是開發(fā)和部署Web service的最基本的內(nèi)容之一。有很多的論文、文檔以及示例說明怎樣保護(hù)Web service,但是這些信息中的絕大多數(shù)所涉及到的都是些有關(guān)理論和實(shí)踐的高級(jí)、抽象的定義,很少人提及其具體實(shí)現(xiàn)。

在這個(gè)三部系列的第一部分,我們將通過一個(gè)使用定制的SOAP HEADER的例子來討論一些有關(guān)具體編程的Web service安全性。示例Web service將使用cookie去獲取用戶的安全環(huán)境(context),從而在方法間維護(hù)狀態(tài),Web service消費(fèi)者將使用一個(gè)Windows應(yīng)用程序來實(shí)現(xiàn)。

一個(gè)可重用安全模式

典型的Web service一般是作為一個(gè)ASP.NET應(yīng)用的附加功能或者API而存在的。Web service既可以直接地與數(shù)據(jù)庫交互,也可以在一個(gè)N層解決方案中通過調(diào)用中間件來完成其功能。在應(yīng)用程序中Web service需要知道是誰調(diào)用了它以及那個(gè)用戶具有什么樣的特權(quán)。

多數(shù)情況下,用戶、角色、商業(yè)規(guī)則以及授權(quán)是已經(jīng)實(shí)現(xiàn)了的,你只要簡(jiǎn)單地提取這些信息。Web service需要實(shí)現(xiàn)一個(gè)模式以確定請(qǐng)求客戶的信任憑證。理論上在Web service中可以傳遞用戶ID和密碼給每個(gè)方法,但是一個(gè)更面向?qū)ο蟮姆椒ㄊ莿?chuàng)建一個(gè)繼承System.Web.Services.Protocols.SoapHeader的類。這個(gè)類將成為我們的SOAP Header,它將被傳遞到Web service,其中包含我們用來驗(yàn)證用戶的所有信息。

服務(wù)器實(shí)現(xiàn)

下面的列表1給出了一個(gè)簡(jiǎn)單Web service的服務(wù)器端實(shí)現(xiàn)代碼,SecureWebServiceTester.asmx,以及相關(guān)的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類擴(kuò)展了SoapHeader類,它告訴.NET Framework它是一個(gè)Soap Header并且允許在<WebMethod()>屬性中被參考。主類SecureWebServicesTester包含了Web services的實(shí)際實(shí)現(xiàn)了的方法,這些方法由<WebMethod()>屬性標(biāo)示。

LoginUser()函數(shù)接受我們的SecureContext Soap Header類的一個(gè)實(shí)例,它像使用其他對(duì)象一樣使用這個(gè)傳入的對(duì)象。注意對(duì)象名字在引號(hào)中被參考的,并且與secureCtx類屬性匹配。

然后這個(gè)方法就通過檢查usrId和secureCtx對(duì)象中的密碼變量來完成驗(yàn)證。如果LoginUser()方法確認(rèn)用戶是合法的,它就產(chǎn)生一個(gè)驗(yàn)證單據(jù),并將其插入響應(yīng)的cookie集合中。

HelloWorld()方法是一個(gè)一旦客戶端得到驗(yàn)證以后你可以在Web service中調(diào)用的一個(gè)很普通的方法。這個(gè)模式需要較少的代碼,因?yàn)樵谝粋€(gè)session中只需進(jìn)行一次授權(quán),然后就可以簡(jiǎn)單地將Web service實(shí)現(xiàn)邏輯包裝起來。

If Context.User.Identity.IsAuthenticated = True Then...

客戶端實(shí)現(xiàn)

現(xiàn)在Web service已經(jīng)實(shí)現(xiàn)并且可以運(yùn)行,我們需要編寫Web service消費(fèi)者。這個(gè)模式的不足之處是客戶端必須啟用cookie以維護(hù)安全單據(jù)。典型的客戶端一般都是一個(gè)Web瀏覽器,明顯地它提供內(nèi)建cookie處理功能,如果用戶沒有禁用它。但是如果客戶端是一個(gè)桌面Windows應(yīng)用程序,那么如何去訪問Web service呢?列表2的示例代碼給出了如何從Windows應(yīng)用程序中消費(fèi)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

要正確的實(shí)現(xiàn)我們的Web service,我們必須導(dǎo)入(Import)System.Net.CookieContainer。這樣我們就可以創(chuàng)建一個(gè)名為CookieContainer1的CookieContainer對(duì)象的示例,它存儲(chǔ)Web service中LoginUser()方法返回的驗(yàn)證單據(jù)。下一步我們將創(chuàng)建Web service自身的一個(gè)實(shí)例:

Private WSObj As New

SecureWebServiceTesterProxy.SecureWebServiceTester().

它必須在form一級(jí)聲明,因?yàn)槲覀兊尿?yàn)證單據(jù)必須在Windows Form中實(shí)現(xiàn)的各種方法間維護(hù)狀態(tài)。至于New()方法,則是由VS.NET產(chǎn)生的,我們將Web service對(duì)象的CookieContainer屬性設(shè)置為cookieContainer1對(duì)象。這將告訴Web service對(duì)象使用cookie container對(duì)象存儲(chǔ)由Web service返回的任何cookie。

要從其它的ASP.NET應(yīng)用中消費(fèi)Web service,除了手工的Cookie存儲(chǔ)代碼外,其它部分的代碼幾乎完全一樣。從一個(gè)桌面應(yīng)用程序消費(fèi)Web service提供了一個(gè)強(qiáng)大的功能、靈活性以及可擴(kuò)展性。

你安全嗎?

上面的代碼只是一個(gè)簡(jiǎn)單的示例,說明了怎樣通過編程拒絕沒有合法驗(yàn)證單據(jù)的客戶端訪問Web service來保護(hù)你的Web service。在你的安全模型中要求的復(fù)雜級(jí)別應(yīng)該由你的商業(yè)需求決定。如果應(yīng)用程序中數(shù)據(jù)的敏感度比較高,那么就應(yīng)該有一個(gè)測(cè)量尺度來保證你的消費(fèi)者的數(shù)據(jù)盡量安全、秘密。

當(dāng)然并不是所有的應(yīng)用程序都需要上面的安全模式,尤其是在你的Web service可以自由使用的時(shí)候。但是其它的應(yīng)用程序就需要嚴(yán)格安全尺度,他們的賣點(diǎn)就是其安全級(jí)別。

發(fā)布:2007-03-25 10:37    編輯:泛普軟件 · xiaona    [打印此頁]    [關(guān)閉]
相關(guān)文章:
上海OA系統(tǒng)
聯(lián)系方式

成都公司:成都市成華區(qū)建設(shè)南路160號(hào)1層9號(hào)

重慶公司:重慶市江北區(qū)紅旗河溝華創(chuàng)商務(wù)大廈18樓

咨詢:400-8352-114

加微信,免費(fèi)獲取試用系統(tǒng)

QQ在線咨詢