asp.net|訪問|網路 對於許多ASP.NET開發人員而言,共用資源的訪問是一個重大挑戰,當開發Web表單和Web服務時就會遇到這樣的挑戰。微軟公司的.NET擁有全新的使用者授權和認證措施,大多數與安全相關的文章和書籍都用相當的篇幅解釋表單認證,但是,與IIS、網路和作業系統安全相結合來理解ASP.NET安全架構是提供最佳解決方案的關健。
圖1描述了由IIS和ASP.NET提供的基本安全表示,它與ASP安全相比有根本不同。上面的圖來自MSDN的網站。當有Web請求發生時,下面的事件會依次發生。
1、使用者發出HTTP請求。
2、當Web請求發生時,它會由以SYSTEM帳戶啟動並執行IIS獲得。SYSTEM帳戶的功能非常強大,而且擁有所有類型的許可權。IIS根據選擇的認證類型進行認證,並為每名經過認證的使用者建立一個存取權杖。如果選擇了了匿名認證,它就會為該匿名使用者建立一個存取權杖,預設情況下是IUSR_MACHINE。另外,ISS還根據配置的授與類型進行認證。例如,IIS能夠配置得只接受來自特定IP地址的請求。
3、IIS將請求和被認證使用者的Windows存取權杖傳遞給aspnet_isepi.dll,這是一個註冊為處理.aspx URL的ISAPI擴充。Aspnet_isepi.dll是一個IIS模組,是IIS和ASP.NET已耗用時間環境之間的一座橋。Aspnet_isapi通過具名管道向工作者進程轉寄該請求。
4、該工作者進程是託管著CLR的aspnet_wp.exe。預設情況下,工作者進程以ASPNET帳戶運行。當安裝ASP.NET架構時,系統會建立該本地帳戶。與功能強大的SYSTEM帳戶不同的是,ASPNET帳戶的功能十分有限。ASP.NET根據其認證配置對要求者進行認證。認證以XML格式配置在該項目的web.config檔案中。如果ASP.NET被配置為Windows認證,它會接受任何來自IIS的令牌,而不會進行其它認證。另外,ASP.NET還授權對請求的資源和檔案的訪問。例如,FileAuthorizationModel可以用來檢查使用者是否具有訪問請求的資源所需要的許可權。對於Windows認證而言,使用者的存取權杖為ACL。
5、如果整個過程發展到了這一步,應用軟體就會使用特定的身份訪問資源。預設情況下,ASPNET進程帳戶提供這一身份。但是,如果允許模仿,可以使用使用者原來的身份或對模仿進行配置,使應用程式能夠以特定的身份運行。
既然安全措施已經闡明,在假設NTFC的許可權被設定為網路資源的情況下,使用者就可以訪問資料了。在進一步向前發展之前,有二個重要問題需要解決。一個是指定和定義訪問UNC共用上檔案和檔案夾的任務,換句話說,也就是訪問網路上共用的檔案和檔案夾。另一個問題是決定用來完成資源訪問任務的身份。為了完成第一個任務,需要首先完成第二個任務。
有幾種方法可以用來訪問網路資源:
·使用ASP.NET進程身份
·使用匿名使用者帳戶
·使用LogonUser API
·使用服務性的組件(企業服務)
使用ASP.NET進程身份似乎有很明顯的缺陷。預設情況下,當應用程式試著訪問資源時,ASP.NET進程身份提供一個身份(ASPNET)。最簡單的解決方案是建立一個具有與遠端電腦上相匹配的使用者名稱和密碼的本地帳戶。大多數企業都會有龐大的內連網,因此這一方法是不切實際的。另外,知道是誰在訪問資源也是非常重要的。儘管該方法足以訪問網路資源,但效率不夠高;第二個方法是使用匿名帳戶,例如IUSR_MACHINE。與上面的原因相同,這種方法的效率顯然也不高;第三種方法是使用LogonUser API,這種方法要求通過調用Win32 LogonUser API模仿一個特定的身份,還可以通過配置ASP.NET項目web.config檔案中的<identity>元素進行模仿。據MSDN上的一篇文章稱,不建議使用者使用以上這些方法,應當避免在Windows 2000伺服器上使用它們,因為它們要求向ASP.NET帳戶進程授予“作為作業系統一部分運行”的許可權,從而極大地降低了web應用程式的安全性。因此,該方法也不理想。最後,也是最可行的解決該問題的方法是使用配置為作為用於訪問網路資源固定身份啟動並執行服務性組件。這種方法聽起來令人膽怯,但它是目前最好的解決方案,它的架構如下圖所示:
梅耶在http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetch08.asp上發表的一一篇有關安全的文章中表示,在企業服務伺服器應用程式中使用服務性組件有以下好處:
·在使用的身份方面的靈活性,不必只依賴於ASP.NET身份。
·受信任或許可權較高的代碼能夠與主web應用程式隔離。
·增加的進程躍距提高了攻擊難度,它使得駭客更難跨越進程的邊界,使用具有較高許可權的進程。
·如果需要手動處理LogonUser API調用的模仿,我們可以在一個與主Web應用程式隔離的進程中完成這一工作。
開發服務性組件
從COM+中接受服務的組合體被稱作服務性組件。為了開發服務性組件,開發人員必須具備豐富的COM+技術經驗。COM+應用程式不是傳統意義上的應用程式,它不包含使用者介面。COM+應用程式實際上是構成應用程式的組件、COM和.NET的容器,它不是新版的COM,也不是COM和DCOM的組合,而是遺傳自MTS(微軟事務服務)的一種技術。
下面是開發服務性組件所需要的步驟:
1、建立一個新類庫項目,以開發作為Web應用程式類庫的中介層組件。
2、添加合適的類、方法和屬性。由於需要訪問檔案和檔案夾,我們需要引入System.IO名字空間。
3、建立一個Web表單應用程式。
現在就可以對組件進行測試了。為了在企業服務應用程式中實現較高的安全性,必須使用Windows認證實現模仿,這一工作可以在Web應用程式的web.config檔案中實現。它使得服務性組件能夠認證調用者,並根據調用者的身份作出授權決策。在開發期間,儘管組件還不是服務性組件,它仍然能夠為訪問共用檔案和檔案夾提供足夠的安全性。
<authentication mode="Window" />
<identity impersonate="true" />
要進行測試,需要首先對類進行編譯,然後將對象的引用添加到Web應用程式中。對類進行如下所示的初始化:
Dim objEnterprise As New AccessingSharedResources.dal_AccessNetwork()
4、建立強命名組合體
·通過依次選擇Start Menu --> Programs --> Microsoft Visual Studio .NET --> Visual Studio .NET Tools --> Visual Studio .NET Command Prompt運行Visual Studio .NET Command Prompt。
·找到項目所在的目錄,並輸入下面的命令:sn -k KeyPair.snk。
·上面的命令會建立一個公/私密金鑰對,Visual Studio .NET IDE可以用它們給我們的組件一個強命名。另外需要注意的是,在項目目錄中建立了一個KeyPair.snk檔案。
·開啟AssemblyInfo.vb檔案代碼視窗,並添加下面的Assembly屬性:
<Assembly: AssemblyKeyFile("KeyPair.snk")>
·編譯該項目。這將建立強命名的組合體。
5. Add the object to the GAC (Global Assembly Cache)
6、在GAC(全域群組合體緩衝區)中添加對象
·通過點擊Start Menu --> Programs --> Administrative Tools --> Microsoft .NET Framework Configuration開啟.NET架構組態工具。
·點擊Select Assembly Cache --> Select View List of Assemblies in the Assembly Cache瀏覽GAC中所有的組合體。
·右擊Assembly Cache表徵圖,從快顯功能表中選擇Add。
·找到該項目的bin目錄中的AccessingSharedResources.dll檔案,並雙擊它。
注意:如果命令提示行視窗仍然在運行,輸入gacutil /i AccessingSharedResources.dll,也能夠將對象添加到GAC中。這是在GAC中添加對象的第二種方法。
7、添加System.EnterpiseServices.dll的引用
8、引入恰當的Enterprise Services名字空間
·Imports System.EnterpriseServices
·Imports System.Runtime.CompilerServices
·Imports System.Reflection
9、在各個類中繼承ServicedComponent類
Public Class dal_AccessNetwork
Inherits ServicedComponent
10、在支援服務性組件的AssemblyInfo.vb檔案中添加與服務性組件相關的組合體屬性。
·引入System.EnterpriseServices名字空間
·添加下面的代碼:
'COM+應用程式名稱字
< Assembly: ApplicationName("AccessingSharedResources")>
'COM+啟用類型
<Assembly: ApplicationActivation(ActivationOption.Server)>
11、設定AssemblyVersion:
據MSDN上的文章(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetch09.asp)稱,當新項目建立時由Microsoft Visual Studio(r) .NET開發系統產生的預設AssemblyVersion屬性是<Assembly: AssemblyVersion("1.0.*")>。每當項目重建時,就會產生新的組合體版本,這也會產生識別服務性組件類的新的類識別符(CLSID)。如果使用Regsvcs.exe重複向組合體註冊元件服務,就會在Components檔案夾中看到具有不同CLSID的複製的組件。
儘管這符合嚴格的COM規則,能夠阻止現有的可管理和不可管理的客戶破壞它,在開發過程中仍然是非常煩人的。在測試和開發過程中,考慮通過使用如下所示的組合體級AssemblyVersion屬性設定一個明確的版本:
<Assembly: AssemblyVersion("1.0.0.1")>
這一設定將阻礙每次編譯項目時產生新的CLSID。
12、產生新的COM+應用程式,在新的COM+應用程式中註冊該組合體
·運行Visual Studio .NET Command Prompt。
·找到bin目錄中dll檔案的位置。
·輸入regsvcs /c AccessingSharedResources.dll,並鍵入斷行符號。
13、修改Web應用程式
·添加System.EnterrpiseServices.dll的引用
·在web用戶端軟體中添加Imports System.EnterpriseServices語句
到這一步,服務性組件就全部完成了。我們可以將該組件看作一個COM+應用軟體。
·通過選擇Start --> Programs --> Administrative Tools --> Component Services運行Component Services Manager。
·擴充Console Root --> Component Services --> Computers --> My Computer --> COM+ Applications --> AccessingSharedResources--> Components。
優點和缺點
使用服務性組件的優點如下所示:
·使用身份的靈活性,我們無須只依賴ASP.NET身份。
·受信任或許可權較高的代碼可以與主Web應用軟體隔離。
·增加的進程躍距提高了系統的安全性,使得駭客更難跨過進程邊界,接近許可權較高的進程。
·如果需要處理帶有LogonUser API調用的模仿,我們可以在與主Web應用軟體隔離的進程中完成。
缺點如下所示:
·調用服務性組件的速度不如本地.NET對象快,因此應用軟體的效能會受到影響。
·要求多餘的步驟和代碼。
·與本地.NET對象相比更難管理。
·需要在COM+應用軟體中安裝DLL。
結論
儘管沒有利用對象集中、事物支援、同步、事件跟蹤等COM+的準系統,我們已經完成了我們的對象。只在COM+應用程式中安裝本地.NET類和添加數行特殊的COM+代碼就足以完成在網路上訪問共用資源的任務。