ASP.NET 2.0 中的 Windows 身份驗(yàn)證

2010-08-28 10:50:18來源:西部e網(wǎng)作者:

適用于:ASP.NET 2.0 版 Windows Server 2003 Internet 信息服務(wù) (IIS) 6.0

摘要:本教程闡釋在 ASP.NET 2.0 版中,IIS 集成 Windows 身份驗(yàn)證以及 ASP.NET Windows 身份驗(yàn)證的工作機(jī)制。同時(shí),闡釋 NTLM 和 Kerberos 身份驗(yàn)證的工作機(jī)制。此外,本教程還闡釋 WindowsAuthenticationModule 類如何構(gòu)造 WindowsPrincipal 和 WindowsIdentity 對(duì)象,然后將這些對(duì)象附加到當(dāng)前的 ASP.NET Web 請(qǐng)求以表示經(jīng)過身份驗(yàn)證的用戶。

目標(biāo)

了解 ASP.NET 2.0 版中 Windows 身份驗(yàn)證的工作機(jī)制。

了解 Kerberos 身份驗(yàn)證的工作機(jī)制。

了解 NTLM 身份驗(yàn)證的工作機(jī)制。

了解 WindowsAuthenticationModule 類如何創(chuàng)建 WindowsPrincipalWindowsIdentity 對(duì)象。

了解模擬如何影響 WindowsPrincipalWindowsIdentity 對(duì)象。

 

概述

身份驗(yàn)證是一個(gè)驗(yàn)證客戶端身份的過程,通常采用指定的第三方授權(quán)方式。客戶端可能是最終用戶、計(jì)算機(jī)、應(yīng)用程序或服務(wù)?蛻舳说臉(biāo)識(shí)稱為安全原則。為了使用服務(wù)器應(yīng)用程序進(jìn)行驗(yàn)證,客戶端提供某種形式的憑據(jù)來允許服務(wù)器驗(yàn)證客戶端的標(biāo)識(shí)。確認(rèn)了客戶端的標(biāo)識(shí)后,應(yīng)用程序可以授予執(zhí)行操作和訪問資源的原則。

如果應(yīng)用程序使用 Active Directory 用戶存儲(chǔ),則應(yīng)該使用集成 Windows 身份驗(yàn)證。對(duì) ASP.NET 應(yīng)用程序使用集成 Windows 身份驗(yàn)證時(shí),最好的方法是使用 ASP.NET 的 Windows 身份驗(yàn)證提供程序附帶的 Internet 信息服務(wù) (IIS) 身份驗(yàn)證方法。使用該方法,將自動(dòng)創(chuàng)建一個(gè) WindowsPrincipal 對(duì)象(封裝一個(gè) WindowsIdentity 對(duì)象)來表示經(jīng)過身份驗(yàn)證的用戶。您無需編寫任何身份驗(yàn)證特定的代碼。

ASP.NET 還支持使用 Windows 身份驗(yàn)證的自定義解決方案(避開了 IIS 身份驗(yàn)證)。例如,可以編寫一個(gè)根據(jù) Active Directory 檢查用戶憑據(jù)的自定義 ISAPI 篩選器。使用該方法,必須手動(dòng)創(chuàng)建一個(gè) WindowsPrincipal 對(duì)象。

本文闡釋在具有 IIS 6.0 的 ASP.NET 2.0 中 Windows 身份驗(yàn)證的工作機(jī)制。

 

IIS 身份驗(yàn)證

如果 ASP.NET 針對(duì) Windows 身份驗(yàn)證進(jìn)行配置,則 ASP.NET 依靠 IIS,利用配置好的身份驗(yàn)證模式對(duì)其客戶端進(jìn)行身份驗(yàn)證。IIS 通過檢查特定應(yīng)用程序的元數(shù)據(jù)庫設(shè)置來確定其身份驗(yàn)證模式。成功驗(yàn)證某個(gè)用戶的身份后,IIS 將代表經(jīng)過身份驗(yàn)證的用戶的 Windows 令牌傳遞給宿主 ASP.NET 的 ASP.NET 輔助進(jìn)程 (w3wp.exe)。如果應(yīng)用程序使用在 IIS 中配置的虛擬目錄來支持匿名訪問,該令牌代表匿名 Internet 用戶帳戶;否則,該令牌代表經(jīng)過身份驗(yàn)證的用戶。

IIS 支持以下身份驗(yàn)證模式:

匿名。如果不需要對(duì)客戶端進(jìn)行身份驗(yàn)證(或者使用自定義身份驗(yàn)證機(jī)制,如窗體身份驗(yàn)證),則可將 IIS 配置為允許匿名訪問。在該事件中,IIS 創(chuàng)建一個(gè) Windows 令牌來表示具有相同匿名(或客人)帳戶的所有匿名用戶。默認(rèn)的匿名帳戶是 IUSR_MACHINENAME,其中 MACHINENAME 是安裝期間指定的計(jì)算機(jī)的 NetBIOS 名稱。

基本;旧矸蒡(yàn)證要求用戶以用戶名和密碼的形式提供憑據(jù)來證明他們的身份;旧矸蒡(yàn)證基于 Internet 標(biāo)準(zhǔn) RFC 2617,所有常用瀏覽器都支持它。用戶的憑據(jù)以未加密的 Base64 編碼格式從瀏覽器傳送到 Web 服務(wù)器。為了更好保護(hù)這些憑據(jù),只要在使用基本身份驗(yàn)證同時(shí)再使用安全套接字層 (SSL) 即可。由于 Web 服務(wù)器包含未加密的用戶憑據(jù),因此 ASP.NET 應(yīng)用程序可以模擬調(diào)用方并使用他們的憑據(jù)來訪問網(wǎng)絡(luò)資源。

集成的 Windows。集成的 Windows 身份驗(yàn)證(以前稱為 NTLM,也稱為 Windows NT 質(zhì)詢/應(yīng)答身份驗(yàn)證,Windows NT Challenge/Response)是使用 Kerberos v5 身份驗(yàn)證還是 NTLM 身份驗(yàn)證,取決于客戶端和服務(wù)器的配置。服務(wù)器與客戶端協(xié)商確定要使用的協(xié)議。如果滿足以下條件,則使用 Kerberos 身份驗(yàn)證:

ASP.NET Web 應(yīng)用程序正在 NetworkService 帳戶或自定義域帳戶下運(yùn)行。如果應(yīng)用程序在本地帳戶(如 Windows 2000 Server 上的 ASPNET 帳戶)上運(yùn)行,則使用 NTLM 身份驗(yàn)證。

域帳戶的 Active Directory 中有一個(gè)服務(wù)主要名稱 (SPN),該域帳戶用于運(yùn)行客戶端進(jìn)行身份驗(yàn)證所使用的服務(wù)。

客戶端計(jì)算機(jī)和服務(wù)器計(jì)算機(jī)至少需要運(yùn)行 Windows 2000 Server,且處在相同的(即信任的)Windows 域中。

默認(rèn)情況下,對(duì)于 Windows Server 2003 操作系統(tǒng)啟用集成 Windows 身份驗(yàn)證。然而,如果 Windows Server 2003 Service Pack 1 (SP1) 作為 Windows Server 2003 操作系統(tǒng)整合安裝的一部分進(jìn)行安裝,則默認(rèn)情況下禁用集成 Windows 身份驗(yàn)證。如果使用 SP1 升級(jí) Windows Server 2003,則集成 Windows 身份驗(yàn)證的設(shè)置與其 Windows Server 2003 設(shè)置相同。

應(yīng)該使用集成 Windows 身份驗(yàn)證而不是基本身份驗(yàn)證,因?yàn)榍罢弑苊饬送ㄟ^網(wǎng)絡(luò)傳輸用戶憑據(jù)。由于 Kerberos v5 身份驗(yàn)證支持相互身份驗(yàn)證,因此用戶還可以對(duì)正在連接的服務(wù)器進(jìn)行身份驗(yàn)證。

集成 Windows 身份驗(yàn)證最適合于 Intranet 環(huán)境,其中的客戶端計(jì)算機(jī)和 Web 服務(wù)器計(jì)算機(jī)都是相同(即信任的)域的一部分。

 

NTLM 身份驗(yàn)證

NTLM 是用于 Windows NT 和 Windows 2000 Server 工作組環(huán)境的身份驗(yàn)證協(xié)議。它還用在必須對(duì) Windows NT 系統(tǒng)進(jìn)行身份驗(yàn)證的混合 Windows 2000 Active Directory 域環(huán)境中。當(dāng) Windows 2000 Server 轉(zhuǎn)換為不存在下層 Windows NT 域控制器的本機(jī)模式時(shí),禁用 NTLM。然后 Kerberos v5 變成企業(yè)級(jí)的默認(rèn)身份驗(yàn)證協(xié)議。

NTLM 身份驗(yàn)證機(jī)制

圖 1 顯示 NTLM 協(xié)議。

\

1. NTLM 質(zhì)詢/應(yīng)答機(jī)制

下面概述質(zhì)詢/應(yīng)答機(jī)制:

用戶請(qǐng)求訪問。用戶嘗試通過提供用戶憑據(jù)登錄到客戶端。登錄前,客戶端計(jì)算機(jī)緩存密碼的哈希值并放棄密碼?蛻舳讼蚍⻊(wù)器發(fā)送一個(gè)請(qǐng)求,該請(qǐng)求包括用戶名以及純文本格式的請(qǐng)求。

服務(wù)器發(fā)送質(zhì)詢消息。服務(wù)器生成一個(gè)稱為質(zhì)詢的 16 字節(jié)隨機(jī)數(shù)(即 NONCE),并將它發(fā)送到客戶端。

客戶端發(fā)送應(yīng)答消息?蛻舳耸褂糜捎脩舻拿艽a生成的一個(gè)密碼哈希值來加密服務(wù)器發(fā)送的質(zhì)詢。它以應(yīng)答的形式將這個(gè)加密的質(zhì)詢發(fā)回到服務(wù)器。

服務(wù)器將質(zhì)詢和應(yīng)答發(fā)送到域控制器。服務(wù)器將用戶名、原始質(zhì)詢以及應(yīng)答從客戶端計(jì)算機(jī)發(fā)送到域控制器。

域控制器比較質(zhì)詢和應(yīng)答以對(duì)用戶進(jìn)行身份驗(yàn)證。域控制器獲取該用戶的密碼哈希值,然后使用該哈希值對(duì)原始質(zhì)詢進(jìn)行加密。接下來,域控制器將加密的質(zhì)詢與客戶端計(jì)算機(jī)的應(yīng)答進(jìn)行比較。如果匹配,域控制器則發(fā)送該用戶已經(jīng)過身份驗(yàn)證的服務(wù)器確認(rèn)。

服務(wù)器向客戶端發(fā)送應(yīng)答。假定憑據(jù)有效,服務(wù)器授予對(duì)所請(qǐng)求的服務(wù)或資源的客戶端訪問權(quán)。

 

Kerberos 身份驗(yàn)證

與 NTLM 身份驗(yàn)證相比,Kerberos 身份驗(yàn)證具有以下優(yōu)勢(shì):

相互身份驗(yàn)證。當(dāng)客戶端使用 Kerberos v5 協(xié)議對(duì)特定服務(wù)器上的特定服務(wù)進(jìn)行身份驗(yàn)證,Kerberos 為客戶端提供網(wǎng)絡(luò)上惡意代碼不會(huì)模擬該服務(wù)的保證。

委托支持。使用 Kerberos 身份驗(yàn)證對(duì)客戶端進(jìn)行身份驗(yàn)證的服務(wù)器可以模擬這些客戶端,并使用該客戶端的安全上下文訪問網(wǎng)絡(luò)資源。

性能。Kerberos 身份驗(yàn)證提供優(yōu)于 NTLM 身份驗(yàn)證的改進(jìn)的性能。

簡(jiǎn)化的信任管理。具有多個(gè)域的網(wǎng)絡(luò)不再需要一組復(fù)雜的顯式、點(diǎn)對(duì)點(diǎn)信任關(guān)系。

互操作性。Microsoft 實(shí)現(xiàn)的 Kerberos 協(xié)議基于向 Internet 工程任務(wù)組 (IETF) 推薦的標(biāo)準(zhǔn)跟蹤規(guī)范。因此,Windows 2000 中協(xié)議的實(shí)現(xiàn)為與其他網(wǎng)絡(luò)的互操作奠定了基礎(chǔ)(其中 Kerberos 版本 5 用于身份驗(yàn)證)。

Kerberos 身份驗(yàn)證機(jī)制

圖 2 顯示 Kerberos 身份驗(yàn)證協(xié)議的簡(jiǎn)化視圖。

\

2. Kerberos 身份驗(yàn)證

當(dāng)客戶端對(duì)網(wǎng)絡(luò)服務(wù)進(jìn)行身份驗(yàn)證之后,Kerberos v5 協(xié)議遵循以下步驟:

客戶端從 KDC 請(qǐng)求 TGT。用戶試圖通過提供用戶憑據(jù)登錄到客戶端?蛻舳擞(jì)算機(jī)上的 Kerberos 服務(wù)向密鑰發(fā)行中心 (KDC) 發(fā)送一個(gè) Kerberos 身份驗(yàn)證服務(wù)請(qǐng)求。該請(qǐng)求包含用戶名、請(qǐng)求票證授予票證(ticket-granting ticket,TGT)所獲取的服務(wù)信息,以及使用用戶的長(zhǎng)期密鑰(即密碼)加密的時(shí)間戳。

在 Windows 2000 Server 或 Windows Server 2003 操作系統(tǒng)上,域控制器充當(dāng) KDC,而 Active Directory 宿主安全帳戶數(shù)據(jù)庫。

身份驗(yàn)證服務(wù)發(fā)送加密的 TGT 和會(huì)話密鑰。KDC 為來自 Active Directory 的用戶獲取長(zhǎng)期密鑰(即密碼),然后解密隨請(qǐng)求一起傳送的時(shí)間戳。如果該時(shí)間戳有效,則用戶是真正的用戶。KDC 身份驗(yàn)證服務(wù)創(chuàng)建一個(gè)登錄會(huì)話密鑰,并使用用戶的長(zhǎng)期密鑰對(duì)該副本進(jìn)行加密。然后,該身份驗(yàn)證服務(wù)創(chuàng)建一個(gè) TGT,它包括用戶信息和登錄會(huì)話密鑰。最后,該身份驗(yàn)證服務(wù)使用自己的密鑰加密 TGT,并將加密的會(huì)話密鑰和加密的 TGT 傳遞給客戶端。

客戶端從 TGT 請(qǐng)求服務(wù)器訪問?蛻舳耸褂闷溟L(zhǎng)期密鑰(即密碼)解密登錄會(huì)話密鑰,并在本地緩存它。此外,客戶端還將加密的 TGT 存儲(chǔ)在它的緩存中。訪問網(wǎng)絡(luò)服務(wù)時(shí),客戶端向 KDC 票證授予服務(wù)(ticket-granting service,TGS)發(fā)送一個(gè)包含信息的請(qǐng)求,這些信息包括用戶名、使用用戶登錄會(huì)話密鑰加密的驗(yàn)證者消息、TGT,以及用戶想訪問的服務(wù)(和服務(wù)器)名稱。

TGS 發(fā)送加密的會(huì)話密鑰和票證。KDC 上的 TGS 使用自己的密鑰解密 KDC 并提取登錄會(huì)話密鑰。它使用該登錄會(huì)話密鑰解密驗(yàn)證者消息(通常是時(shí)間戳)。如果驗(yàn)證者消息成功解密,TGS 從 TGT 提取用戶信息,并使用用戶信息創(chuàng)建一個(gè)用于訪問該服務(wù)的服務(wù)會(huì)話密鑰。它使用該用戶的登錄會(huì)話密鑰對(duì)該服務(wù)會(huì)話密鑰的一個(gè)副本進(jìn)行加密,創(chuàng)建一個(gè)具有服務(wù)會(huì)話密鑰和用戶信息的服務(wù)票證,然后使用該服務(wù)的長(zhǎng)期密鑰(密碼)對(duì)該服務(wù)票證進(jìn)行加密。然后,TGS 將加密的服務(wù)會(huì)話密鑰和服務(wù)票證添加到客戶端。

客戶端發(fā)送服務(wù)票證?蛻舳嗽L問服務(wù)時(shí),向服務(wù)器發(fā)送一個(gè)請(qǐng)求。該請(qǐng)求包含驗(yàn)證者消息(時(shí)間戳),該消息使用服務(wù)會(huì)話密鑰和服務(wù)票證進(jìn)行加密。

服務(wù)器發(fā)送加密的時(shí)間戳以進(jìn)行客戶端驗(yàn)證。服務(wù)器解密服務(wù)票證并提取服務(wù)會(huì)話密鑰。通過使用服務(wù)會(huì)話密鑰,服務(wù)器解密驗(yàn)證者消息(時(shí)間戳)并計(jì)算它。如果驗(yàn)證者通過測(cè)試,則服務(wù)器使用服務(wù)會(huì)話密鑰對(duì)驗(yàn)證者(時(shí)間戳)進(jìn)行加密,然后將驗(yàn)證者傳回到客戶端?蛻舳私饷軙r(shí)間戳,如果該時(shí)間戳與原始時(shí)間戳相同,則該服務(wù)是真正的,客戶端繼續(xù)連接。

服務(wù)的主要名稱

Kerberos v5 身份驗(yàn)證協(xié)議之所以使用服務(wù)的主要名稱 (SPN),原因如下:

支持相互身份驗(yàn)證。

允許一個(gè)客戶端請(qǐng)求票證,進(jìn)而允許該客戶端與特定服務(wù)通訊。

例如,如果某個(gè)客戶端需要獲得一個(gè)票證,并對(duì)在偵聽端口 4766 運(yùn)行的計(jì)算機(jī) (MyServer) 上的特定服務(wù) (MyService) 進(jìn)行身份驗(yàn)證,則該客戶端使用根據(jù)該信息構(gòu)造的名稱從 KDC 請(qǐng)求一個(gè)票證,如下所示:

MyService/MyServer:4766

在 Active Directory 中注冊(cè)的 SPN 在該名稱和運(yùn)行所請(qǐng)求的服務(wù)的域帳戶之間維護(hù)一個(gè)映射。通過使用該機(jī)制,惡意用戶難以在網(wǎng)絡(luò)上模擬服務(wù)。惡意用戶必須禁用實(shí)際服務(wù)并從該網(wǎng)絡(luò)移除實(shí)際服務(wù)器。然后,惡意用戶必須向網(wǎng)絡(luò)中添加一臺(tái)同名的新計(jì)算機(jī)并公開重復(fù)的服務(wù)。由于客戶端使用具有相互身份驗(yàn)證的 Kerberos v5 協(xié)議,因此該客戶端將無法使用重復(fù)的服務(wù),除非它可以提供配置實(shí)際服務(wù)進(jìn)行運(yùn)行的域帳戶的密碼。

 

ASP.NET 身份驗(yàn)證

IIS 向 ASP.NET 傳遞代表經(jīng)過身份驗(yàn)證的用戶或匿名用戶帳戶的令牌。該令牌在一個(gè)包含在 IPrincipal 對(duì)象中的 IIdentity 對(duì)象中維護(hù),IPrincipal 對(duì)象進(jìn)而附加到當(dāng)前 Web 請(qǐng)求線程?梢酝ㄟ^ HttpContext.User 屬性訪問 IPrincipalIIdentity 對(duì)象。這些對(duì)象和該屬性由身份驗(yàn)證模塊設(shè)置,這些模塊作為 HTTP 模塊實(shí)現(xiàn)并作為 ASP.NET 管道的一個(gè)標(biāo)準(zhǔn)部分進(jìn)行調(diào)用,如圖 3 所示。

\

3. ASP.NET 管道

ASP.NET 管道模型包含一個(gè) HttpApplication 對(duì)象、多個(gè) HTTP 模塊對(duì)象,以及一個(gè) HTTP 處理程序?qū)ο蠹捌湎嚓P(guān)的工廠對(duì)象。HttpRuntime 對(duì)象用于處理序列的開頭。在整個(gè)請(qǐng)求生命周期中,HttpContext 對(duì)象用于傳遞有關(guān)請(qǐng)求和響應(yīng)的詳細(xì)信息。

有關(guān) ASP.NET 請(qǐng)求生命周期的詳細(xì)信息,請(qǐng)參閱"ASP.NET Life Cycle",網(wǎng)址是 http://msdn2.microsoft.com/library/ms227435(en-US,VS.80).aspx。

身份驗(yàn)證模塊

ASP.NET 2.0 在計(jì)算機(jī)級(jí)別的 Web.config 文件中定義一組 HTTP 模塊。其中包括大量身份驗(yàn)證模塊,如下所示:

<httpModules>

  <add name="WindowsAuthentication"
    type="System.Web.Security.WindowsAuthenticationModule" />
  <add name="FormsAuthentication" 
    type="System.Web.Security.FormsAuthenticationModule" />
  <add name="PassportAuthentication" 
    type="System.Web.Security.PassportAuthenticationModule" />

</httpModules>

只加載一個(gè)身份驗(yàn)證模塊,這取決于該配置文件的 authentication 元素中指定了哪種身份驗(yàn)證模式。該身份驗(yàn)證模塊創(chuàng)建一個(gè) IPrincipal 對(duì)象并將它存儲(chǔ)在 HttpContext.User 屬性中。這是很關(guān)鍵的,因?yàn)槠渌跈?quán)模塊使用該 IPrincipal 對(duì)象作出授權(quán)決定。

當(dāng) IIS 中啟用匿名訪問且 authentication 元素的 mode 屬性設(shè)置為 none 時(shí),有一個(gè)特殊模塊將默認(rèn)的匿名原則添加到 HttpContext.User 屬性中。因此,在進(jìn)行身份驗(yàn)證之后,HttpContext.User 絕不是一個(gè)空引用(在 Visual Basic 中為 Nothing)。

WindowsAuthenticationModule

如果 Web.config 文件包含以下元素,則激活 WindowsAuthenticationModule 類。

<authentication mode="Windows" />

WindowsAuthenticationModule 類負(fù)責(zé)創(chuàng)建 WindowsPrincipalWindowsIdentity 對(duì)象來表示經(jīng)過身份驗(yàn)證的用戶,并且負(fù)責(zé)將這些對(duì)象附加到當(dāng)前 Web 請(qǐng)求。

對(duì)于 Windows 身份驗(yàn)證,遵循以下步驟:

WindowsAuthenticationModule 使用從 IIS 傳遞到 ASP.NET 的 Windows 訪問令牌創(chuàng)建一個(gè) WindowsPrincipal 對(duì)象。該令牌包裝在 HttpContext 類的 WorkerRequest 屬性中。引發(fā) AuthenticateRequest 事件時(shí),WindowsAuthenticationModuleHttpContext 類檢索該令牌并創(chuàng)建 WindowsPrincipal 對(duì)象。HttpContext.User 用該 WindowsPrincipal 對(duì)象進(jìn)行設(shè)置,它表示所有經(jīng)過身份驗(yàn)證的模塊和 ASP.NET 頁的經(jīng)過身份驗(yàn)證的用戶的安全上下文。

WindowsAuthenticationModule 類使用 P/Invoke 調(diào)用 Win32 函數(shù)并獲得該用戶所屬的 Windows 組的列表。這些組用于填充 WindowsPrincipal 角色列表。

WindowsAuthenticationModule 類將 WindowsPrincipal 對(duì)象存儲(chǔ)在 HttpContext.User 屬性中。隨后,授權(quán)模塊用它對(duì)經(jīng)過身份驗(yàn)證的用戶授權(quán)。

注:DefaultAuthenticationModule 類(也是 ASP.NET 管道的一部分)將 Thread.CurrentPrincipal 屬性設(shè)置為與 HttpContext.User 屬性相同的值。它在處理 AuthenticateRequest 事件之后進(jìn)行此操作。

授權(quán)模塊

WindowsAuthenticationModule 類完成其處理之后,如果未拒絕請(qǐng)求,則調(diào)用授權(quán)模塊。授權(quán)模塊也在計(jì)算機(jī)級(jí)別的 Web.config 文件中的 httpModules 元素中定義,如下所示:

<httpModules>
  <add name="UrlAuthorization" 
    type="System.Web.Security.UrlAuthorizationModule" />
  <add name="FileAuthorization" 
    type="System.Web.Security.FileAuthorizationModule" />
  <add name="AnonymousIdentification" 
    type="System.Web.Security.AnonymousIdentificationModule" />
</httpModules>

UrlAuthorizationModule

調(diào)用 UrlAuthorizationModule 類時(shí),它在計(jì)算機(jī)級(jí)別或應(yīng)用程序特定的 Web.config 文件中查找 authorization 元素。如果存在該元素,則 UrlAuthorizationModule 類從 HttpContext.User 屬性檢索 IPrincipal 對(duì)象,然后使用指定的動(dòng)詞(GET、POST 等)來確定是否授權(quán)該用戶訪問請(qǐng)求的資源。

FileAuthorizationModule

接下來,調(diào)用 FileAuthorizationModule 類。它檢查 HttpContext.User.Identity 屬性中的 IIdentity 對(duì)象是否是 WindowsIdentity 類的一個(gè)實(shí)例。如果 IIdentity 對(duì)象不是 WindowsIdentity 類的一個(gè)實(shí)例,則 FileAuthorizationModule 類停止處理。

如果存在 WindowsIdentity 類的一個(gè)實(shí)例,則 FileAuthorizationModule 類調(diào)用 AccessCheck Win32 函數(shù)(通過 P/Invoke)來確定是否授權(quán)經(jīng)過身份驗(yàn)證的客戶端訪問請(qǐng)求的文件。如果該文件的安全描述符的隨機(jī)訪問控制列表 (DACL) 中至少包含一個(gè) Read 訪問控制項(xiàng) (ACE),則允許該請(qǐng)求繼續(xù)。否則,FileAuthorizationModule 類調(diào)用 HttpApplication.CompleteRequest 方法并將狀態(tài)碼 401 返回到客戶端。

 

安全上下文

.NET Framework 使用以下兩個(gè)接口封裝 Windows 令牌和登錄會(huì)話:

System.Security.Principal.IPrincipal

System.Security.Principal.IIdentity(它公開為 IPrincipal 接口中的一個(gè)屬性。)

HttpContext.User

在 ASP.NET 中,用 WindowsPrincipalWindowsIdentity 類表示使用 Windows 身份驗(yàn)證進(jìn)行身份驗(yàn)證的用戶的安全上下文。使用 Windows 身份驗(yàn)證的 ASP.NET 應(yīng)用程序可以通過 HttpContext.User 屬性訪問 WindowsPrincipal 類。

要檢索啟動(dòng)當(dāng)前請(qǐng)求的 Windows 經(jīng)過身份驗(yàn)證的用戶的安全上下文,使用以下代碼:

using System.Security.Principal;
...
// Obtain the authenticated user's Identity
WindowsPrincipal winPrincipal = (WindowsPrincipal)HttpContext.Current.User;

WindowsIdentity.GetCurrent

WindowsIdentity.GetCurrent 方法可用于獲得當(dāng)前運(yùn)行的 Win32 線程的安全上下文的標(biāo)識(shí)。如果不使用模擬,線程繼承 IIS 6.0(默認(rèn)情況下的 NetworkService 帳戶)上進(jìn)程的安全上下文。

該安全上下文在訪問本地資源時(shí)使用。通過使用經(jīng)過身份驗(yàn)證的初始用戶的安全上下文或使用固定標(biāo)識(shí),您可以使用模擬重寫該安全上下文。

要檢索運(yùn)行應(yīng)用程序的安全上下文,使用以下代碼:

using System.Security.Principal;
...
// Obtain the authenticated user's identity.
WindowsIdentity winId = WindowsIdentity.GetCurrent();
WindowsPrincipal winPrincipal = new WindowsPrincipal(winId);

Thread.CurrentPrincipal

ASP.NET 應(yīng)用程序中的每個(gè)線程公開一個(gè) CurrentPrincipal 對(duì)象,該對(duì)象保存經(jīng)過身份驗(yàn)證的初始用戶的安全上下文。該安全上下文可用于基于角色的授權(quán)。

要檢索線程的當(dāng)前原則,使用以下代碼:

using System.Security.Principal;
...
// Obtain the authenticated user's identity
WindowsPrincipal winPrincipal = (WindowsPrincipal) Thread.CurrentPrincipal();

表 1 顯示從各種標(biāo)識(shí)屬性獲得的結(jié)果標(biāo)識(shí),當(dāng)您的應(yīng)用程序使用 Windows 身份驗(yàn)證且 IIS 配置為使用集成 Windows 身份驗(yàn)證時(shí),可以從 ASP.NET 應(yīng)用程序使用這些標(biāo)識(shí)屬性。

表 1:線程公開的 CurrentPrincipal Object
Web.config 設(shè)置 變量位置 結(jié)果標(biāo)識(shí)

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

HttpContext
WindowsIdentity
線程

Domain\UserName
Domain\UserName
Domain\UserName

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

HttpContext
WindowsIdentity
線程

Domain\UserName
NT AUTHORITY\NETWORK SERVICE
Domain\UserName

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

HttpContext
WindowsIdentity
線程

用戶提供的名稱
Domain\UserName
用戶提供的名稱

<identity impersonate="false"/>
<authentication mode="Forms" />

HttpContext
WindowsIdentity
線程

用戶提供的名稱
NT AUTHORITY\NETWORK SERVICE
用戶提供的名稱

 

模擬

ASP.NET 應(yīng)用程序可以使用模擬來執(zhí)行操作,使用經(jīng)過身份驗(yàn)證的客戶端或特定 Windows 帳戶的安全上下文來訪問資源。

初始用戶模擬

要模擬初始(經(jīng)過身份驗(yàn)證的)用戶,請(qǐng)?jiān)?Web.config 文件中使用以下配置:

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

使用該配置,ASP.NET 始終模擬經(jīng)過身份驗(yàn)證的用戶,且所有資源訪問均使用經(jīng)過身份驗(yàn)證的用戶的安全上下文執(zhí)行。如果您的應(yīng)用程序的虛擬目錄上啟用了匿名訪問,則模擬 IUSR_MACHINENAME 帳戶。

要暫時(shí)模擬經(jīng)過身份驗(yàn)證的調(diào)用方,將 identity 元素的 impersonate 屬性設(shè)置為 false,然后使用以下代碼:

using System.Security.Principal;
...
// Obtain the authenticated user's identity.
WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsImpersonationContext ctx = null;
try
{
    // Start impersonating.
    ctx = winId.Impersonate();
    // Now impersonating.
    // Access resources using the identity of the authenticated user.
}
// Prevent exceptions from propagating.
catch
{
}
finally
{
    // Revert impersonation.
    if (ctx != null)
        ctx.Undo();
}
// Back to running under the default ASP.NET process identity.

這段代碼模擬經(jīng)過身份驗(yàn)證的初始用戶。在 HttpContext.Current.User.Identity 對(duì)象中維護(hù)初始用戶的標(biāo)識(shí)和 Windows 令牌。

固定標(biāo)識(shí)模擬

如果需要在應(yīng)用程序的整個(gè)生命周期中模擬相同的標(biāo)識(shí),可以在 Web.config 文件中的 identity 元素上指定憑據(jù)。以下示例顯示如何模擬名為"TestUser"的 Windows 帳戶。

如果使用該方法,應(yīng)該對(duì)這些憑據(jù)進(jìn)行加密。使用 ASP.NET 2.0,您可以使用 ASP.NET IIS 注冊(cè)工具 (Aspnet_regiis.exe)。使用 ASP.NET 1.1 版,您可以使用 Aspnet_setreg.exe 實(shí)用工具。有關(guān)該實(shí)用工具的詳細(xì)信息,請(qǐng)參閱 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpgrfaspnetiisregistrationtoolaspnet_regiisexe.asp。

要在 ASP.NET 應(yīng)用程序中使用固定標(biāo)識(shí)進(jìn)行資源訪問,可使用 Windows 2000 Server 或 Windows Server 2003 上的 identity 元素來配置憑據(jù)。如果正在運(yùn)行 Windows Server 2003,其中的 IIS 6.0 配置為運(yùn)行在輔助進(jìn)程隔離模式下(默認(rèn)情況),則可通過將 ASP.NET 應(yīng)用程序配置為在自定義應(yīng)用程序池(在特定的域標(biāo)識(shí)下運(yùn)行)中運(yùn)行來避免模擬。然后,可以使用指定的域標(biāo)識(shí)訪問資源而無需使用模擬。

 

委托

模擬只提供對(duì)本地資源的訪問。委托是一個(gè)擴(kuò)展的模擬功能,它允許您使用模擬令牌訪問網(wǎng)絡(luò)資源。

如果應(yīng)用程序使用 Kerberos v5 身份驗(yàn)證對(duì)其用戶進(jìn)行身份驗(yàn)證,則可使用 Kerberos 委托在應(yīng)用程序的各層傳遞用戶標(biāo)識(shí)并訪問網(wǎng)絡(luò)資源。如果應(yīng)用程序不使用 Kerberos v5 身份驗(yàn)證,則可使用協(xié)議轉(zhuǎn)換切換到 Kerberos,然后使用委托傳遞該標(biāo)識(shí)。

Windows Server 2003 中的約束委托需要 Kerberos 身份驗(yàn)證。如果您的應(yīng)用程序無法使用 Kerberos 身份驗(yàn)證對(duì)其調(diào)用方進(jìn)行身份驗(yàn)證,您可以使用協(xié)議轉(zhuǎn)換從可選的非 Windows 身份驗(yàn)證模式(如,窗體或證書身份驗(yàn)證)切換到 Kerberos 身份驗(yàn)證。然后,可使用具有約束委托的 Kerberos 訪問下游網(wǎng)絡(luò)資源。

約束的和未約束的委托

Windows 2000 Server 上的 Kerberos 委托是未約束的。Active Directory 中配置了委托的服務(wù)器可在使用模擬的用戶安全上下文的同時(shí)訪問任何網(wǎng)絡(luò)資源或網(wǎng)絡(luò)上的任何計(jì)算機(jī)。這會(huì)帶來潛在的安全威脅,尤其是 Web 服務(wù)器遭受惡意用戶攻擊時(shí)。

為了解決該安全問題,Windows Server 2003 引入了約束的委托。這使管理員能夠在使用模擬的用戶安全上下文時(shí)準(zhǔn)確指定另一個(gè)服務(wù)器或域帳戶可以訪問的服務(wù)。

配置委托

要使用 Kerberos 委托,需要適當(dāng)?shù)?Active Directory 配置。

要授予 Web 服務(wù)器委托客戶端憑據(jù)的權(quán)限,請(qǐng)按以下方式配置 Active Directory:

如果在 NetworkService 帳戶下運(yùn)行應(yīng)用程序,Web 服務(wù)器計(jì)算機(jī)帳戶必須在 Active Directory 中標(biāo)記為受信任委托。

如果在自定義域帳戶下運(yùn)行應(yīng)用程序,該用戶帳戶必須在 Active Directory 中標(biāo)記為受信任委托。

如果應(yīng)用程序模擬一個(gè)用戶帳戶,請(qǐng)確保應(yīng)用程序模擬的用戶帳戶在 Active Directory 中未標(biāo)記為"敏感帳戶,不能被委托"。

有關(guān)協(xié)議轉(zhuǎn)換和約束委托的詳細(xì)信息,請(qǐng)參閱 How To: Use Protocol Transition and Constrained Delegation in ASP.NET 2.0。

 

其他資源

How To: Use Windows Authentication in ASP.NET 2.0

 

反饋

使用 Wiki 或電子郵件提供反饋:

Wiki。Security Guidance Feedback Wiki 頁: http://channel9.msdn.com/wiki/default.aspx/Channel9.SecurityGuidanceFeedback

電子郵件。請(qǐng)將電子郵件發(fā)送至 secguide@microsoft.com

我們對(duì)有關(guān)以下內(nèi)容的反饋特別感興趣:

特定于建議的技術(shù)問題

有用性和可用性問題

 

技術(shù)支持

本指南中涉及的 Microsoft 產(chǎn)品和技術(shù)的支持由 Microsoft Support Services 提供。有關(guān)產(chǎn)品支持信息,請(qǐng)?jiān)L問 Microsoft Support 的 Web 站點(diǎn):http://support.microsoft.com

 

社區(qū)和新聞組

論壇和新聞組中提供社區(qū)支持:

MSDN 新聞組http://msdn.microsoft.com/newsgroups/default.asp

ASP.NET 論壇http://forums.asp.net

要想獲益最多,請(qǐng)找到與您的技術(shù)或問題對(duì)應(yīng)的新聞組。例如,如果有 ASP.NET 安全功能方面的問題,可查閱 ASP.NET Security 論壇。

 

投稿人與審閱者

外部投稿人和審閱者: Jason Taylor,Security Innovation;Rudolph Araujo,F(xiàn)oundstone Professional Services

Microsoft PSS 投稿人和審閱者: Tom Christian, Wade Mascia

Microsoft 產(chǎn)品小組: Stefan Schackow

測(cè)試小組: Larry Brader,Microsoft Corporation;Nadupalli Venkata Surya Sateesh、Sivanthapatham Shanmugasundaram,Infosys Technologies Ltd.

編輯小組: Lara Ballinger、Nelly Delgado,Microsoft Corporation

發(fā)布管理: Sanjeev Garg,Microsoft Corporation

關(guān)鍵詞:ASP.NET