身份驗證和授權

身份驗證和授權

發佈日期: 9/29/2004 | 更新日期: 9/29/2004

瀏覽全部的安全性指導主題

Microsoft Corporation

本章內容

爲分佈式 Web 應用程序設計身份驗證和授權機制是一項具有挑戰性的任務,您必須做出的選擇中有許多幾乎會對您開發的應用程序的每個組件產生影響。採用合適的身份驗證和授權設計方案有助於降低許多主要的安全風險。在應用程序開發的早期階段實現這樣的設計比嘗試改進現有的或已部分構建的應用程序解決方案來得輕鬆許多。

本章描述了在開發分佈式 ASP.NET Web 應用程序時可用的身份驗證和授權機制。同時描述一個您可採用,有助於爲您的應用程序選擇最合適的身份驗證和授權機制的過程。

目標

利用本章來:

瞭解通過多個應用程序層的流身份的各種選項。

確定在分佈式 Web 應用程序中使用的合適的身份驗證和授權機制。

比較和對比在分佈式 .NET Web 應用程序中用於身份驗證和授權的“模擬/委派”(也就是“原調用者”)和“受信任子系統”模式之間的異同。

比較和對比基於角色和基於資源的授權方式。

適用於:

本章內容適用於以下產品和技術:

Microsoft Windows XP 或 Windows 2000 Server (帶 service pack 3),以及更高版本的操作系統。

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

Microsoft Active Directory 目錄服務

.NET Framework 1.0 版(帶 service pack 2)和更高版本

SQL Server™ 2000(帶 service pack 2)和更高版本

如何使用本章

本章描述爲分佈式 Web 應用程序確定合適的身份驗證和授權機制的過程。越早考慮應用程序的身份驗證和授權要求,這些機制就能越早實現,應用程序也可能越安全。要想從本章獲得最大價值,您應該:

閱讀本章中的“構建安全的 ASP.NET 應用程序介紹”。它定義了與分佈式 Web 應用程序相關的“身份驗證”和“授權”術語。

閱讀本章中的“用於 ASP.NET 應用程序的安全模式”。它概述了創建分佈式 ASP.NET Web 應用程序所使用的體系結構和技術。它介紹本章深入討論的身份驗證和授權機制,並定義授權主題的核心內容—網關和網關守衛的概念。

閱讀以下章節,它們論證本章所討論的身份驗證和授權技術的實現:

How To Create a Custom Account to Run ASP.NET”。

How To Use 表單 Authentication with Active Directory”。

How To Use 表單 Authentication with SQL Server 2000”。

How To Use 表單 Authentication with Generic Principal Objects”。

How To Implement Kerberos Delegation for Windows 2000”。

How To Implement IPrincipal”。

How To Use Role-based Security with Enterprise Services”。

How To Call a Web Service Using Client Certificates from ASP.NET”。

How To Setup Client Certificates”。

*
本頁內容
準備工作 準備工作
設計身份驗證和授權策略 設計身份驗證和授權策略
授權方法 授權方法
傳遞身份 傳遞身份
基於角色授權 基於角色授權
選擇身份驗證機制 選擇身份驗證機制
小結 小結

準備工作

爲分佈式 Web 應用程序設計一種身份驗證和授權策略是一項具有挑戰性的任務。 令人欣慰的是,在應用程序開發的早期階段,正確設計身份驗證和授權將有助於降低許多安全方面的主要風險。

本章將幫助您爲應用程序設計適當的授權策略,也將幫助您解答下列關鍵問題:

應該在什麼情況下執行授權,使用什麼機制?

應該使用什麼身份驗證機制?

應該用 Active Directory 目錄服務來進行身份驗證,還是應該對照自定義數據存儲來驗證憑證?

使用異類和同類平臺分別意味着什麼?在設計上有哪些需要注意的地方?

在應用程序中應該如何表示沒有使用 Windows 操作系統的用戶?

應該如何在應用程序的各層之間傳遞用戶身份? 在什麼情況下應該使用操作系統級模擬/委派?

當您考慮授權時,也必須考慮身份驗證。兩個過程是同時進行的,這有兩方面的原因:

首先,任何有意義的授權策略都要求已驗證身份的用戶。

其次,驗證用戶身份的方式(具體說,就是如何在應用程序中表示已通過驗證的用戶身份)將決定您可支配的網關守衛。

某某些網關守衛,(如, ASP.NET 文件授權、Enterprise Services (COM+) 角色和 Windows ACL) 都需要一個通過身份驗證的 Windows 身份(以 WindowsIdentity 對象的形式存在,它封裝了一個定義調用者安全上下文的 Windows 訪問令牌。) 而其他網關守衛,(如 ASP.NET URL 授權和 .NET 角色)則沒有這一要求。它們只要求身份通過驗證即可,並不需要一定是由 Windows 訪問令牌來表示。

設計身份驗證和授權策略

以下步驟確定了幫助您爲應用程序制定身份驗證和授權策略的過程:

標識資源。

選擇授權策略。

選擇用於資源訪問的身份。

考慮身份傳遞。

選擇身份驗證方法。

決定如何傳遞身份。

確定資源

確定應用程序需要向客戶端公開的資源。典型資源包括:

Web Server 資源,例如 Web 頁面、Web 服務、靜態資源(HTML 頁面和圖像)。

數據庫資源,例如每用戶數據或應用程序範圍的數據。

網絡資源,例如遠程文件系統資源和來自目錄存儲(如 Active Directory)的數據。

還必須確定應用程序需要訪問的系統資源。這些資源與向客戶端公開的資源相反,是不公開的。 它們包括註冊表、事件日誌和配置文件。

選擇授權策略

有兩種基本的授權策略:

基於角色。對操作(通常是方法)的訪問是基於調用者的角色成員保護的。 使用角色將應用程序的用戶羣分成在應用程序內共享相同安全特權的用戶組;例如“高級經理”、“經理”和“職員”。用戶被映射到角色,如果用戶有權所請求的操作,則應用程序就會使用固定的身份訪問資源。這些身份受各自的資源管理器(例如數據庫、文件系統等)所信任。

基於資源。使用 Windows ACL 分別保護各個資源。應用程序在調用者訪問資源前先對其進行模擬,這樣使操作系統可以執行標準的訪問檢查。所有資源訪問都是通過原調用者的安全上下文執行的。 此模擬方法嚴重影響應用程序的可擴展性,因爲這意味着在應用程序的中間層無法有效地使用連接池。

在絕大多數必須進行擴展的 .NET Web 應用程序中,基於角色授權方法是最好的選擇。而某些規模較小的 Intranet 應用程序則從各種資源(如文件)中提取單個用戶信息,當各個用戶訪問這些資源時,這些資源是通過 Windows ACL 加以保護的,因此更適合採用基於資源的授權方式。

在進行基於角色授權時,推薦使用和常見的做法是:

在前端 Web 應用程序中驗證用戶身份。

將用戶映射到角色。

基於角色成員授權對操作(而不是直接對資源)進行訪問。

使用固定的服務身份訪問必要的後端資源(用來支持所請求的和授權的操作)。後端資源管理器(例如,數據庫) 信任 應用程序可以授權調用者,並且願意授予權限給受信任的服務身份。

例如,數據庫管理員可能只授予訪問特定人力資源應用程序(而不是個別用戶)的訪問權限。

應用程序級別的基於角色授權方式仍然需要使用基於資源的授權來保護系統級資源,例如配置文件、註冊表項等。

更多信息

有關這兩種截然不同的授權方式的更多信息,請參考本章後面的“授權方式”。

有關基於角色授權和各種可以使用的角色類型的更多信息,請參考本章後面的“基於角色授權”。

選擇用於資源訪問的身份

請回答這樣的問題:“誰將訪問資源?”

選擇用來在應用程序各個層進行資源訪問的身份。這些資源可以由基於 Web 的應用程序來訪問,還可以由 Web 服務、Enterprise Service 和 .NET 遠程處理組件訪問。一般來講,用於資源訪問的身份可以是以下幾類:

原調用者的身份。它採用一種模擬/委派模式,即可以獲得原調用方身份,然後將此身份在系統的每一層之間傳遞。委派因素是用於確定身份驗證機制的重要標準。

進程身份。這是默認情況(沒有具體的模擬)。使用當前進程身份可以訪問本地資源並進行下游調用。這一方法是否可靠取決於所跨越的界限,因爲進程身份必須被目標系統識別。

這意味着要用以下方式之一進行調用:

在同一個 Windows 安全域中

跨 Windows 安全域(使用信任和域帳戶,如果不存在信任關係,則使用重複的用戶名和密碼)

服務帳戶。本方法使用一個(固定的)服務帳戶。例如:

對於數據庫訪問,它可以是與數據庫連接提供的固定 SQL 用戶名和密碼。

當需要固定的 Windows 身份時,則可以使用 Enterprise Services 服務器應用程序。

自定義身份。當沒有可用的 Windows 帳戶時,您可以構造自己的身份(使用 IPrincipal 和 IIdentity 模擬),它將包含您指定的安全上下文的具體內容。例如,它可以包含角色列表、惟一標識符或任何其他類型的自定義信息。

通過用 IPrincipalIIdentity 類型實現自定義身份並將它們放置在當前 Web 上下文(使用 HttpContext.User),您可以直接從內置的網關守衛(如 .NET 角色和 PrincipalPermission 命令)中獲益。

考慮身份傳遞

爲了支持每用戶授權、審覈和每用戶數據檢索,您可能需要在不同的應用程序層之間和不同計算機之間傳遞調用者身份。例如,如果某個後端資源管理器需要執行每用戶授權,調用者身份就必須傳遞給該資源管理器。

您要根據系統的資源管理器授權要求和審覈要求來確定需要在應用程序中傳遞的身份。

選擇身份驗證方式

影響身份驗證方式選擇有兩個關鍵因素:第一,也是最重要的因此是,應用程序的用戶羣的特點(他們使用哪一類瀏覽器以及他們是否有 Windows 帳戶);第二是,應用程序的模擬/委派和審覈要求。

更多信息

有關幫助您爲應用程序選擇身份驗證機制的更多具體考慮事項,請參考本章後面的“選擇身份驗證機制”。

決定如何傳遞身份

您可以在應用程序級傳遞身份(以提供安全上下文),也可以在操作系統級傳遞身份和安全上下文。

要在應用程序級傳遞身份,請使用方法和存儲過程參數。應用程序身份傳遞支持:

使用受信任的查詢參數檢索每用戶數據

    SELECT x,y FROM SomeTable WHERE username="bob" 

在任何應用程序層中自定義審覈

操作系統身份傳遞支持:

平臺級審覈(例如,Windows 審覈和 SQL Server 審覈)

基於 Windows 身份的每用戶授權

爲了在操作系統級傳遞身份,您可以使用模擬/委派模式。在有些環境下,可以使用 Kerberos 委派,而在其他環境下(多半是不支持 Kerberos 的環境),您可能需要使用其他方法,例如使用基本身份驗證。在基本身份驗證下,用戶憑證可由服務器應用程序使用,還可以用於訪問下游網絡資源。

更多信息

有關身份傳遞以及如何用網絡憑證獲得模擬令牌(即支持委派)的更多信息,請參考本章後面的“傳遞身份”。

授權方法

有兩種基本的授權方法:

基於角色。用戶被劃分爲由應用程序定義的邏輯角色。在應用程序中,某一特定角色的成員將共享相同的特權。對操作的訪問(通常由方法調用表示)是根據調用者的角色成員授權的。

可以用固定身份(例如 Web 應用程序身份或 Web 服務進程身份)訪問資源。資源管理器信任應用程序可以正確授權用戶,並且它們將權限授予 受信任 的身份。

基於資源。各個資源是通過 Windows ACL 保護的。ACL 將決定哪些用戶允許訪問資源,還決定允許每個用戶執行哪類操作(讀、寫、刪除等)。

可以使用原調用者的身份(使用模擬)訪問資源。

基於角色授權

在基於角色(或操作)的安全方法中,對操作(而非後端資源)的訪問是根據調用者的角色成員進行授權的。(在應用程序設計時分析和定義的)角色被用作邏輯容器,它們將在應用程序中共享相同安全特權(或功能)的用戶組合起來。用戶被映射到應用程序中的角色,而角色成員用來控制對由應用程序公開的特定操作(方法)的訪問權。

在應用程序的什麼位置映射角色是設計中需要考慮的一個關鍵因素;例如:

在一種極端情況下,可以在後端資源管理器(例如數據庫)中映射角色。它要求原調用者的安全上下文通過應用程序的各層傳遞到後端數據庫。

另一種極端情況是在前端 Web 應用程序中映射角色。在這種方法中,下游資源管理器是通過由每個資源管理器授權並受其信任的固定身份訪問的。

第三種情況是在前端和後端層之間的某個位置進行角色映射;例如,在中間層 Enterprise Services 應用程序中。

在多層 Web 應用程序中,使用受信任的身份訪問後端資源管理器爲應用程序提供更大的可擴展空間(這歸功於連接池)。另外,使用受信任身份減少了在操作系統級傳遞原調用者安全上下文的需要,而這是很難以實現的(即使在某些情況下並非不可能實現)。

基於資源的授權

基於資源的授權方法依賴於 Windows ACL 和操作系統基本的訪問控制機制。應用程序模擬調用者,將執行訪問檢查的任務留給與特定資源管理器(文件系統、數據庫等)關聯的操作系統。

這種方法最適合於這樣的應用程序,即用它們來訪問可通過 Windows ACL 單獨保護的資源,如文件資源。FTP 應用程序或簡單的數據驅動 Web 應用程序就屬於這類應用程序。如果被請求資源中的數據需要從多個不同來源(例如,多個數據庫、數據庫表、外部應用程序或 Web 服務)獲得併合並,則這種方法就力不從心了。

基於資源的方法也依賴於傳遞到應用程序後端資源管理器的原調用者安全上下文。這種方法配置複雜,並大大降低了多層應用程序增加受訪的能力,因爲使用這種方法,您就無法在應用程序中間層有效運用集合功能(例如,數據庫連接集合)。

資源訪問模式

通過研究 .NET Web 應用程序(以及一般情況下分佈式多層應用程序)最常用的兩種資源訪問安全模式,我們可以看到兩種截然不同的授權方法。它們是:

受信任的子系統模式

模擬/委派模式

兩種模式在安全和可擴展性方面都各有優缺點。以下部分將介紹這些模式。

受信任的子系統模式

在這種模式中,中間層服務使用固定身份訪問下游服務和資源。原調用者安全上下文不在操作系統級通過服務傳遞,但應用程序可以選擇在應用程序級傳遞原調用者身份。可能需要這樣做才能支持後端審覈要求,或者才能支持每用戶數據訪問和授權。

該模式的名稱源自於下游服務(可能是個數據庫)在授權調用者時信任上游服務。圖 1 顯示了此模式。請特別注意信任界限。在本示例中,數據庫 信任 中間層可以授權調用者,並只允許經授權的調用者通過受信任的身份訪問數據庫。


在受信任的子系統模式中,資源的訪問步驟如下:

驗證用戶身份

將用戶映射到角色

基於角色成員授權

使用固定的受信任身份訪問下游資源管理器

固定身份

用於訪問下游系統和資源管理器的固定身份通常由預配置的 Windows 帳戶(也稱爲服務帳戶)提供。在 Microsoft SQL Server 資源管理器中,這意味着對 SQL Server 使用 Windows 身份驗證。

另外,有些應用程序使用指定的 SQL 帳戶(由連接字符串中的用戶名和密碼指定)訪問 SQL Server。在這種情況下,必須爲數據庫配置 SQL 身份驗證。

有關與 SQL Server 通信時 Windows 和 SQL 身份驗證的相對優缺點的更多信息,請參考“數據訪問安全性”這一章。

使用多個受信任的身份

有些資源管理器可能需要根據調用者的角色成員,執行更進一步細分的授權。例如,您可能有兩組用戶,一組應該授權可執行讀/寫操作,而另一組應該授權執行只讀操作。

請看下面的 SQL Server 方法:

創建兩個 Windows 帳戶,一個用於讀操作,另一個用於讀/寫操作。

更通常的情況是,用不同的帳戶映射應用程序特定的角色。例如,您可能要讓 Internet 用戶使用一個帳戶,讓內部操作員和/或管理員使用另一個帳戶。

將每個帳戶映射爲由 SQL Server 用戶定義的數據庫角色,併爲每個角色建立必要的數據庫權限。

將用戶映射到應用程序中的角色,並使用角色成員身份確定連接到數據庫之前模擬的帳戶。

這種方法如圖 2 所示。


2. 使用多個身份訪問數據庫以支持更細分的授權

模擬/委派模式

在這種模式下,服務或組件在客戶端訪問下一個下游服務之前(通常在邏輯業務服務層中的某處)(使用操作系統級模擬)模擬客戶端的身份。如果下一個服務位於同一臺計算機,則模擬就足夠了。如果下游服務位於一臺遠程計算機,則還需要委派。

委派的結果是,用於下游資源訪問的安全上下文是該客戶端的安全上下文。使用此模式通常有兩個原因:

它允許下游服務通過原調用者的身份執行每調用者授權。

它允許下游服務使用操作系統級審覈功能。

作爲這種技術的一個具體示例,中間層 Enterprise Services 組件可以在調用者訪問一個數據庫之前對其進行模擬。使用依賴於原調用者安全上下文的數據庫連接訪問數據庫。在此模式下,數據庫對每個調用者進行身份驗證,並根據指派給各個調用者的身份(或該調用者的 Windows 組成員)的權限做出授權決定。模擬/委派模式如圖 3 所示。


3. 模擬/委派模式

選擇資源訪問模式

受信任的子系統模式用於絕大多數 Internet 應用程序和大規模的 Intranet 應用程序,這主要是出於可擴展性因素考慮。而模擬模式則往往用於可擴展性不是主要問題的小規模應用程序和那些審覈(由於非拒絕原因)是關鍵問題的應用程序。

模擬/委派模式的優點

模擬/委派模式的主要優點是審覈(與數據接近)。審覈可以讓管理員跟蹤試圖訪問特定資源的用戶。通常,如果審覈是在資源訪問的準確時間、由訪問資源的相同例程生成,則認爲審覈最具權威性。

模擬/委派模式是通過維護用於下游資源訪問的用戶安全上下文來支持這一點的。這樣可以使後端系統權威地記錄用戶和所請求的訪問。

模擬/委派模式的缺點

模擬/委派模式的相關缺點包括:

技術挑戰。大多數安全服務提供商不支持委派,Kerberos 是有名的例外。

執行模擬的進程要求有更高的特權(具體來說就是 作爲操作系統的一部分 的執行特權)。(這限制適用於 Windows 2000,而不適用於 Windows .NET Server)。

可擴展性。模擬/委派模式意味着您不能有效地使用數據庫連接池,因爲執行數據庫訪問的連接依賴於原調用者的不同安全上下文。這嚴重限制了應用程序擴展至大量用戶的能力。

更多的管理工作。在後端資源中維護 ACL 需要授予每個用戶恰當的訪問級別。當後端資源的數量增加(且用戶數增加)時,就需要在管理 ACL 上投入大量的管理精力。

受信任的子系統模式的優點

受信任的子系統模式具有以下優點:

可擴展性。受信任的子系統模式支持連接池,這是應用程序可擴展性的基本要求。連接池允許多個客戶端重複使用可用的池連接。它非常適用此模式,因爲無論調用者的身份是什麼,所有後端資源訪問都使用服務帳戶的安全上下文。

後端 ACL 管理工作減到最少。只有服務帳戶訪問後端資源(例如,數據庫)。ACL 只針對這個身份進行配置。

用戶無法直接訪問數據。在受信任的子系統模式中,只有中間層服務帳戶被授權訪問後端資源。因此,如果不通過應用程序(並且以應用程序授權爲準),用戶無法直接訪問後端數據。

受信任的子系統模式的缺點

受信任的子系統模式有兩個缺點:

審覈。爲了在後端執行審覈,可以顯式地(在應用程序級別)將原調用者的身份傳遞到後端,並在那執行審覈。必須信任中間層,而且確實有潛在的拒絕風險。另一種選擇是,在中間層生成審覈紀錄,然後將它與後端審覈紀錄相關聯(爲此,必須確保服務器時鐘是同步的)。

增加服務器攻擊危險。在受信任的子系統模式中,中間層服務被授權對後端資源的廣泛訪問。因此,安全受威脅的中間層服務就可能使攻擊者更加容易地獲得對後端資源的廣泛訪問權。

傳遞身份

分佈式應用程序可以分成多個安全子系統。例如,前端 Web 應用程序、中間層 Web 服務、遠程組件和數據庫代表四個不同的安全子系統。每一個都執行身份驗證和授權。

您必須識別出那些必須將調用者身份(和相關的安全上下文)傳遞到下游子系統的子系統,這樣才能支持針對原調用者的授權。

應用程序與操作系統身份傳遞對比

身份傳遞策略包括使用操作系統的委派功能或在應用程序級傳遞票證和/或憑證。例如:

爲了在應用程序級傳遞身份,一般使用方法參數或存儲過程參數傳遞憑證(或票證)。

:攜帶經過身份驗證的調用者身份的GenericPrincipal 對象並不會在進程間自動傳遞。這需要自定義代碼。

可以向存儲過程傳遞允許您檢索和處理用戶特定數據的參數。例如:

SELECT CreditLimit From Table Where UserName="Bob" 

這種方法有時也稱爲 受信任的查詢參數 方法。

操作系統身份傳遞需要一種擴展形式的模擬(稱爲委派)。

模擬和委派

在典型情況下,服務器應用程序中的線程使用服務器進程的安全上下文運行。組成進程安全上下文的屬性由進程的登錄會話維護,並由進程級 Windows 訪問令牌公開。所有本地和遠程資源訪問都通過進程級安全上下文執行,而該安全上下文則由用於運行服務器進程的 Windows 帳戶確定。

模擬

爲服務器應用程序配置了模擬後,模擬令牌就會附加到用於處理請求的線程上。模擬令牌代表通過身份驗證的調用者(或匿名用戶)的安全上下文。任何本地資源訪問都是通過導致使用調用者安全上下文的線程模擬令牌執行的。

委派

如果服務器應用程序線程試圖訪問遠程資源,則需要委派。具體地講,被模擬的調用者的令牌必須具有網絡憑證。如果沒有,所有的遠程資源訪問都是以匿名用戶 (AUTHORITY/A否NYMOUS LOGON) 執行的。

有許多因素可以決定是否可以委派安全上下文。表 1 顯示了各種 IIS 身份驗證類型,並對每種類型註明是否可以委派通過身份驗證的調用者的安全上下文。

表 1:IIS 身份驗證類型
身份驗證類型 是否可以委派 備註

匿名

視情況而定

如果匿名帳戶(默認爲 IUSR_MACHINE)在 IIS 中被配置爲本地帳戶,那麼,除非本地(Web 服務器)和遠程計算機有同樣的本地帳戶(具有匹配的用戶名和密碼),否則不能委派它。

如果匿名帳戶是域帳戶,則可以委派它。

基本

如果對本地帳戶使用基本身份驗證,並且只要本地和遠程計算機的本地帳戶一致,就可以委派它。也可以委派域帳戶。

簡要

-

集成 Windows

視情況而定

集成 Windows 身份驗證導致 NTLM 或 Kerberos(取決於客戶端和服務器的操作系統版本)。

NTLM 不支持委派。

Kerberos 支持有恰當配置環境的委派。

有關詳細信息,請參考“How To Implement Kerberos Delegation for Windows 2000”。

客戶端證書

視情況而定

如果與 IIS 證書映射一起使用,並且證書映射到遠程計算機上覆制的本地帳戶或者映射到域帳戶,則可以委派。

這可行的原因是映射帳戶的憑證存儲在本地服務器上,並且用於創建(具有網絡憑證的)交互式的登錄會話。

Active Directory 證書映射不支持委派。

重要: Windows 2000 下的Kerberos 委派是不受限制的。換句話說,用戶或許可以在多臺遠程計算機之間製造多個網絡躍點。爲了消除這種潛在的安全風險,應該限制域帳戶的訪問範圍,方法是從“域用戶”組中刪除此帳戶,並只允許使用此帳戶登錄到特定的計算機。

基於角色授權

大部分 .NET Web 應用程序都使用基於角色的授權方法。您需要考慮各種角色類型,選擇最適合您的應用程序方案的方法。您有以下選項:

.NET 角色

Enterprise Services (COM+) 角色

SQL Server 用戶定義的數據庫角色

SQL Server 應用程序角色

.NET 角色

.NET 角色非常靈活,它圍繞 IPrincipal 對象展開,這些對象包含通過身份驗證的身份所屬的角色列表。.NET 角色可以用於 Web 應用程序、Web 服務,或駐留在 ASP.NET (用 HttpChannel 訪問)中的遠程組件。

授權可以通過 .NET 角色以兩種方式進行:一種以聲明方式用 PrincipalPermission 命令,一種以編程方式,在代碼中用強制的 PrincipalPermission 命令或 IPrincipal.IsInRole 方法。

Windows 身份驗證中的 .NET 角色

如果您的應用程序使用 Windows 身份驗證,則 ASP.NET 會自動構建一個 WindowsPrincipal,並將其附加到當前 Web 請求的上下文(使用 HttpContext.User)。身份驗證過程完成,並且 ASP.NET 將對象附加到當前請求後,它就可用於所有後續的基於 .NET 角色的授權了。

通過身份驗證的調用者的 Windows 組成員用於確定角色集。在 Windows 身份驗證下,.NET 角色與 Windows 組相同。

非 Windows 身份驗證中的 .NET 角色

如果您的應用程序使用非 Windows 身份驗證機制(例如表單或 Passport),那麼您必須編寫代碼來創建 GenericPrincipal 對象(或自定義 IPrincipal 對象),並用從自定義身份驗證數據存儲(如 SQL Server 數據庫)中獲得的角色集填充它。

自定義 IPrincipal 對象

基於 .NET 角色的安全機制是可擴展的。您可以開發實現 IPrincipalIIdentity 的自有類,並提供您自己的基於角色的擴展授權功能。

只要自定義 IPrincipal 對象(包含從自定義數據存儲中獲得的角色)(通過 HttpContext.User)附加到當前請求的上下文,就保證了基本角色的檢查功能。

通過實現 IPrincipal 接口,可以確保聲明和命令形式的PrincipalPermission 命令都適用於您的自定義身份。另外,您可以實現擴展的角色語義;例如,提供允許您測試和斷言多個角色的成員身份的其他方法,比如 IsInMultipleRoles( string [] roles )。

更多信息

有關基於 .NET 角色的授權的更多信息,請參考“ASP.NET 安全性”一章。

有關創建 GenericPrincipal 對象的更多信息,請參考“How To Create GenericPrincipal Objects with 表單 Authentication”一章。

Enterprise Services (COM+) 角色

使用 Enterprise Services (COM+) 角色可以將訪問檢查交給中間層,並允許您在連接到後端數據庫時使用數據庫連接池。然而,對於有意義的基於 Enterprise Services (COM+) 角色的授權,前端 Web 應用程序必須模擬原調用者的身份,並(通過 Windows 訪問令牌)使將其傳遞到 Enterprise Services 應用程序。爲此,必須在 Web 應用程序的 Web.config 文件中放入以下各項。

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

如果使用方法級的說明性檢查(以確定哪些用戶可以調用哪些方法)就足夠的話,則可以使用“組件服務”管理工具部署應用程序和更新角色成員。

如果需要用方法代碼以編程方式進行檢查,您將會失去 Enterprise Services (COM+) 角色的一些管理和部署優點,因爲角色邏輯是硬編碼的。

SQL Server 用戶定義的數據庫角色

在這種方法中,您在數據庫中創建角色,根據角色指派權限,並將 Windows 組和用戶帳戶映射到角色。這種方法要求您將調用者身份傳遞到後端(如果您對 SQL Server 使用首選的 Windows 身份驗證)。

SQL Server 應用程序角色

在這種方法中,將權限授予數據庫中的角色,但 SQL Server 應用程序角色不包含用戶和組帳戶。因此,您就會失去原調用者的粒度。

在應用程序角色中,您被授權訪問特定的應用程序(與一組用戶相對)。此應用程序使用接受角色名和密碼的內置存儲過程激活角色。這種方法的一個主要缺點是它要求應用程序安全地管理憑證(角色名和相關的密碼)。

更多信息

有關 SQL Server 用戶定義的數據庫角色和應用程序角色的更多信息,請參考“數據訪問安全性”一章。

.NET 角色與 Enterprise Services (COM+) 角色的對比

以下表格列出 .NET 角色和 Enterprise Services (COM+) 角色的功能對比。

表 2:Enterprise Services 角色與 .NET 角色的對比
功能 Enterprise Services 角色 .NET 角色

管理

組件服務管理工具

自定義

數據存儲

COM+ 目錄

自定義數據存儲(如 SQL Server 或 Active Directory)

聲明性

命令性

類、接口和方法級粒度

可擴展性

是(使用自定義 IPrincipal 實現)

可供所有 .NET 組件使用

只供派生自 ServicedComponent 基類的組件使用

角色成員

角色包含 Windows 組或用戶帳戶

當使用 WindowsPrincipal 時,角色是 Windows 組–—沒有額外的抽象級別

要求顯式地實現接口

是,要想獲得方法級的授權,必須顯式地定義和實現接口

使用 .NET 角色

可以使用 .NET 角色保護以下各項的安全:

文件

文件夾

Web 頁面(.aspx 文件)

Web 服務(.asmx 文件)

對象

方法和屬性

方法中的代碼塊

可以使用 .NET 角色保護操作(由方法和屬性執行)和特定代碼塊的事實,意味着您可以保護對應用程序所訪問的本地和遠程資源的訪問。

前面列表中的前四項(文件、文件夾、Web 頁面和 Web 服務)是通過 UrlAuthorizationModule 保護的,它可以使用調用者的角色成員(和調用者的身份)做出授權決定。

如果您使用 Windows 身份驗證,則系統會爲您完成使用 .NET 角色所需的大部分工作。ASP.NET 會構建 WindowsPrincipal 對象,並由用戶的 Windows 組成員確定相關的角色集。

要在非 Windows 身份驗證機制中使用 .NET 角色,必須編寫代碼執行以下操作:

捕獲用戶憑證。

檢驗用戶訪問自定義數據存儲(比如 SQL Server 數據庫)的憑證。

檢索角色列表,構建 GenericPrincipal 對象並將它與當前 Web 請求相關聯。

GenericPrincipal 對象代表通過身份驗證的用戶,並用於後續的 .NET 角色檢查,例如聲明性的PrincipalPermission 命令和編程方式的IPrincipal.IsInRole 檢查。

更多信息

有關爲表單身份驗證創建 GenericPrincipal 對象所涉及過程的更多信息,請參考“ASP.NET 安全性”一章。

檢查角色成員

可使用以下類型的 .NET 角色檢查:

重要:.NET 角色檢查依賴於 IPrincipal 對象(表示通過身份驗證的用戶)是否與當前請求關聯。對於 ASP.NET Web 應用程序,IPrincipal 對象必須附加到 HttpContext.User。對於 Windows 窗體應用程序,IPrincipal 對象必須附加到 Thread.CurrentPrincipal

手動角色檢查。對於細分授權,您可以調用 IPrincipal.IsInRole 方法,根據調用者的角色成員授權對特定代碼塊的訪問。在檢查角色成員時,AND 和 OR 邏輯均可使用。

聲明性角色檢查(方法入口)。您可以使用 PrincipalPermissionAttribute 類(可以簡寫爲 PrincipalPermission)對方法進行註釋,以聲明方式請求角色成員。這些檢查只支持 OR 邏輯。例如,您可以要求調用者至少屬於一個特定的角色(例如,調用者必須是出納員或一個經理)。不能用聲明性檢查指定調用者必須既是經理,又是出納員。

命令性角色檢查(在方法中檢查)。可以在代碼中調用 PrincipalPermission.Demand 執行細分授權邏輯。支持邏輯 AND 和 OR 操作。

角色檢查示例

以下代碼片段顯示了一些使用編程、聲明性和命令性方法的角色檢查示例。

授權 Bob 執行操作:

儘管可以授權個別用戶,但通常應該基於角色成員身份進行授權,這使您可以授權在應用程序中共享相同特權的用戶組。

直接用戶名檢查

    GenericIdentity userIdentity = new GenericIdentity("Bob"); 
    if (userIdentity.Name=="Bob") 
    { 
    } 

聲明性檢查

    [PrincipalPermissionAttribute(SecurityAction.Demand, User="Bob")] 
    public void DoPrivilegedMethod() 
    { 
    } 

命令性檢查

    PrincipalPermission permCheckUser = new PrincipalPermission( 
                                                   "Bob", null); 
    permCheckUser.Demand(); 

授權出納員執行操作:

直接角色名檢查

    GenericIdentity userIdentity = new GenericIdentity("Bob"); 
    // Role names would be retrieved from a custom data store 
    string[] roles = new String[]{"Manager", "Teller"}; 
    GenericPrincipal userPrincipal = new GenericPrincipal(userIdentity,  
                                                          roles); 
    if (userPrincipal.IsInRole("Teller")) 
    { 
    } 

聲明性檢查

    [PrincipalPermissionAttribute(SecurityAction.Demand, Role="Teller")] 
    void SomeTellerOnlyMethod() 
    { 
    } 

命令性檢查

    public SomeMethod() 
    { 
      PrincipalPermission permCheck = new PrincipalPermission( 
                                                   null,"Teller"); 
      permCheck.Demand(); 
      // Only Tellers can execute the following code 
      // •ñn members of the Teller role result in a security exception 
      . . . 
    } 

授權經理或出納員執行操作:

直接角色名檢查

    if (Thread.CurrentPrincipal.IsInRole("Teller") || 
        Thread.CurrentPrincipal.IsInRole("Manager")) 
    { 
      // Perform privileged operations 
    } 

聲明性檢查

    [PrincipalPermissionAttribute(SecurityAction.Demand, Role="Teller"), 
     PrincipalPermissionAttribute(SecurityAction.Demand, Role="Manager")] 
    public void DoPrivilegedMethod() 
    { 
    } 

命令性檢查

    PrincipalPermission permCheckTellers = new PrincipalPermission(  
                                                       null,"Teller"); 
    PrincipalPermission permCheckManagers = new PrincipalPermission( 
                                                       null,"Manager"); 
   (permCheckTellers.Union(permCheckManagers)).Demand(); 

授權那些既是經理又是出納員的用戶執行操作:

直接角色名檢查

    if (Thread.CurrentPrincipal.IsInRole("Teller") && 
        Thread.CurrentPrincipal.IsInRole("Manager")) 
    { 
      // Perform privileged operation 
    } 

聲明性檢查

不可以利用 .NET 角色以聲明方式執行 AND 檢查。將 PrincipalPermission 命令疊加在一起使用會產生邏輯 OR。

命令性檢查

    PrincipalPermission permCheckTellers = new PrincipalPermission( 
                                                     null,"Teller"); 
    permCheckTellers.Demand();   
    PrincipalPermission permCheckManagers = new PrincipalPermission( 
                                                     null, "Manager"); 
    permCheckManagers.Demand(); 

選擇身份驗證機制

本部分提供指導信息,旨在幫助您選擇常見應用程序方案的身份驗證機制。您應該考慮從以下問題着手:

身份。僅當應用程序用戶的 Windows 帳戶可由受信任的機構進行身份驗證,並且應用程序的 Web 服務器可以訪問該機構時,才適合使用 Windows 身份驗證機制。

憑證管理。Windows 身份驗證的一個主要優點是它使您可以將憑證管理交給操作系統去做。採用非 Windows 方法(如表單身份驗證),您就必須仔細考慮用戶憑證的存儲位置和方式。兩種最常見的方法是使用:

SQL Server 數據庫

Active Directory 中的用戶對象

有關將 SQL Server 用作憑證存儲的安全考慮事項的更多信息,請參考“數據訪問安全性”一章。

有關在自定義數據存儲(包括 Active Directory)中使用表單身份驗證的更多信息,請參考“ASP.NET 安全性”一章。

身份傳遞。您需要實現模擬/委派模式,並在操作系統級的各層間傳遞原調用者的安全上下文嗎?例如,爲了支持審覈或每用戶(粒度)授權。如果需要,您就需要能夠模擬調用者,並將它們的安全上下文委派到下一個下游子系統,如本章前面的“傳遞身份”部分中的“委派”主題所描述的。

瀏覽器類型。您的用戶都有 Internet Explorer 嗎?或者您需要支持使用混合瀏覽器類型的用戶羣?表 3 闡述了哪些身份驗證機制需要 Internet Explorer 瀏覽器,而哪些支持各種常見的瀏覽器類型。

表 3:身份驗證瀏覽器要求
身份驗證類型 是否要求 Internet Explorer 備註

表單

-

Passport

-

集成 Windows(Kerberos 或 NTLM)

Kerberos 還要求客戶端和服務器使用 Windows 2000 或更高版本的操作系統,並且有爲委派配置的帳戶。要想了解更多信息,請參考“How To Implement Kerberos Delegation for Windows 2000”。

基本

基本身份驗證是幾乎所有瀏覽器都支持的 HTTP 1.1 協議的一部分

簡要

-

證書

客戶端要求 X.509 證書

Internet 方案

Internet 方案的基本假定條件是:

用戶在服務器域或該服務器可達的受信任域中沒有 Windows 帳戶。

用戶沒有客戶端證書。

圖 4 顯示了一個爲 Internet 方案選擇身份驗證機制的決策樹。


4. 爲 Internet 應用程序選擇身份驗證機制

有關 Web 服務安全和 WS 安全規範(全球 XML 體系結構 (GXA) 倡議的一部分)的更多信息,請參考“Web Services Security”一章。

表單/ Passport 比較

這一部分總結表單和 Passport 身份驗證的相對優點。

表單身份驗證的優點

支持對照自定義數據存儲(通常爲 SQL Server 數據庫或 Active Directory)的身份驗證。

支持基於角色授權(包括從數據存儲中查找角色)。

與 Web 用戶界面平穩集成。

ASP.NET 提供結構的大部分。與傳統 ASP 相比,需要的自定義代碼相對較少。

Passport 身份驗證的優點

Passport 是一種集中式解決方案。

它不需要應用程序進行憑證管理。

能與基於角色授權方案一起使用。

非常安全,因爲它建立在加密技術之上。

更多信息

有關 Web 服務身份驗證方法的更多信息,請參考“Web Services Security”一章。

有關在 SQL Server 中使用表單身份驗證的更多信息,請參考“How To Use 表單 Authentication with SQL Server 2000”一章。

Intranet / Extranet 方案

圖 5 顯示了一個可用於幫助爲 Intranet 和 Extranet 應用方案選擇一種身份驗證機制的決策樹。


5. 爲 Intranet 和 Extranet 應用程序選擇一種身份驗證機制

身份驗證機制比較

以下表格顯示可用的身份驗證機制的比較。

表 4:可用的身份驗證方法
- Basic Digest NTLM Kerberos Certs Forms Passport

用戶在服務器的域中需要 Windows 帳戶

支持委派*

可以

需要 Win2K 客戶端和服務器

以明文形式傳遞憑證(需要 SSL)

支持非 IE 瀏覽器

* 有關詳細內容,請參考本章前面的“傳遞身份”部分中的“委派”主題。

小結

設計分佈式應用程序的身份驗證和授權方法是一項具有挑戰性的任務。在應用程序開發的早期階段,正確設計身份驗證和授權有助於減少許多主要的安全風險。以下總結本章中的信息:

使用受信任子系統資源訪問模式可獲得使用數據庫連接池的益處。

如果您的應用程序沒有使用 Windows 身份驗證,請使用 .NET 角色檢查提供授權。對照自定義數據存儲檢驗憑證,檢索角色列表並創建 GenericPrincipal 對象。將它與當前 Web 請求 (HttpContext.User) 相關聯。

如果您的應用程序使用 Windows 身份驗證,但不使用 Enterprise Services,請使用 .NET 角色。請記住,對於 Windows 身份驗證,.NET 角色爲 Windows 組。

如果您的應用程序使用 Windows 身份驗證和 Enterprise Services,請考慮使用 Enterprise Services (COM+) 角色。

對於使用 Enterprise Services (COM+) 角色的有意義的基於角色授權,原調用者的身份必須傳遞到 Enterprise Services 應用程序。如果從 ASP.NET Web 應用程序中調用 Enterprise Services 應用程序,則意味着 Web 應用程序必須使用 Windows 身份驗證,並配置爲使用模擬。

PrincipalPermission 屬性對方法進行註釋,以聲明方式請求角色成員。如果調用者不在指定的角色中,則不調用該方法,並且產生一個安全異常。

在方法代碼中調用 PrincipalPermission.Demand (或使用 IPrincipal.IsInRole)以獲得細分授權決策。

考慮實現自定義 IPrincipal 對象以獲得其他角色檢查語義

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章