IIS 和 ASP.NET 處理
注 本節内容适用于運作在 Windows 2000 上的 Internet 資訊服務 (IIS) 5。
ASP.NET Web 應用程式和 Web 服務由在 ASP.NET 輔助程序 (aspnet_wp.exe) 的單一執行個體中執行的代碼進行處理,即使是在多處理器計算機上,您仍然可以配置多個執行個體(每個處理器一個執行個體)。
IIS 對調用方進行身份驗證并為其建立 Windows 通路令牌。如果在 IIS 内啟用匿名通路,那麼匿名Internet 使用者帳戶(一般為 IUSR_MACHINE)的 Windows 通路令牌由 IIS 建立。
對 ASP.NET 檔案類型的請求由 ASP.NET ISAPI 擴充進行處理 (aspnet_isapi.dll),該擴充運作在 IIS (inetinfo.exe) 程序位址空間中。這将使用命名管道來與 ASP.NET 輔助程序通訊,如圖 1 所示。IIS 将代表調用方的 Windows 通路令牌傳遞給ASP.NET 輔助程序。 ASP.NET Windows 身份驗證子產品用此來構造 WindowsPrincipal 對象,ASP.NET File 身份驗證子產品使用它來執行 Windows 通路檢查,以確定調用方經身份驗證可以通路請求的檔案。

圖 1. IIS 和 ASP.NET 通訊
注 通路令牌與程序有關。是以,在 inetinfo.exe 内運作的 ASP.NET ISAPI DLL 調用 DuplicateHandle,将令牌句柄複制到 aspnet_wp.exe 程序位址空間中,然後通過命名管道傳遞該句柄值。
應用程式隔離
輔助程序中單獨的應用程式域(每個 IIS 虛拟目錄一個,或每個 ASP.NET Web 應用程式或 Web 服務一個)用于提供隔離。
這與傳統的 ASP 相反,在傳統的 ASP 中,應用程式保護級别在 IIS 中繼資料庫内進行配置,以确定 ASP 應用程式應當在帶有 IIS (inetinfo.exe) 的程序中、在專用 Dllhost.exe執行個體中的程序之外還是在共享的(池)Dllhost.exe 執行個體中執行。
重要事項 在 IIS 内設定程序隔離級别對處理 ASP.NET Web 應用程式的方式沒有影響。
ASP.NET ISAPI 擴充
ASP.NET ISAPI 擴充 (aspnet_isapi.dll) 運作在 IIS 程序位址空間 (inetinfo.exe) 中,并将ASP.NET 檔案類型的請求通過命名管道轉發至 ASP.NET 輔助程序。
通過 IIS 中繼資料庫中定義的映射,将指定的 ASP.NET 檔案類型映射到 ASP.NET ISAPI 擴充。在安裝.NET 架構時建立标準 ASP.NET 檔案類型(包括 .aspx, .asmx, .rem, .soap)的映射。
應用程式映射的檢視步驟
1. | 從 AdministrativeTools 程式組啟動 Internet 資訊服務。 |
2. | 滑鼠右鍵單擊 Web 伺服器計算機上的預設 Web 站點,然後單擊 Properties。 |
3. | 單擊 HomeDirectory 頁籤,然後單擊 Configuration。 螢幕顯示映射清單。您可檢視映射到 Aspnet_isapi.dll 的檔案類型。 |
IIS 6.0 和 Windows .NET 伺服器
Windows .NET 伺服器上的 IIS 6.0 會對目前程序排列做出重要更改。
• | 您将能夠配置多個應用程式池,每個池可由一個或多個程序執行個體 (w3wp.exe) 提供服務。這将提供額外的容錯和管理功能,并允許您隔離單獨程序中的單獨應用程式。 |
• | 将 ASP.NET 與 IIS 6.0 Kernel 模式 HTTP 偵聽器內建,可将請求直接從作業系統傳遞至 ASP.NET 輔助程序。 |
更多資訊
有關 IIS6 的詳細資訊,請參閱 TechNet 上的文章“IIS 6 概述” (http://www.microsoft.com/technet/treeview/default.asp?url=/TechNet/prodtechnol/iis/evaluate/iis6ovw.asp)。
傳回頁首
ASP.NET 管道處理
使用 HTTP 子產品對象來實作 ASP.NET 身份驗證和授權機制,這是作為标準 ASP.NET 管道處理的一部積分進行調用的。圖 2 所示為單個 Web 請求和響應通過對象管道傳遞。
圖 2. ASP.NET 管道處理
ASP.NET 管道模型包括一個 HttpApplication 對象、多種 HTTP 子產品對象以及一個 HTTP 句柄對象,還有它們相關的工廠對象(圖 2 将其省略以求畫面清晰)。在處理序列開始時使用 HttpRuntime 對象,在請求的整個生命周期内使用 HttpContext 對象以傳達有關請求和響應的詳細資訊。
下表說明了由與 HTTP 處理管道相關聯的對象執行的職責及操作:
• | HttpRuntime 對象檢查從 IIS 接收的請求,并将它配置設定至 HttpApplication 對象的适當執行個體以進行處理。Aspnet_wp.exe 的每個應用程式域中都有一個 HttpApplication 對象池。在應用程式域、HttpApplication 對象和 IIS 虛拟目錄之間存在着一一映射。即,ASP.NET 将單獨的 IIS 虛拟目錄視為單獨的應用程式。 注 每個 Web 應用程式域中都有一個 HttpRuntime 執行個體。 |
• | HttpApplication 對象控制管道處理。建立單個 HttpApplication 對象來處理每個同時發出的 HTTP 請求。HttpApplication 對象由于性能原因彙集入池。 |
• | HTTP 子產品對象是在 HTTP 請求和響應消息通過管道時對其進行處理的篩選器。它們可檢視或更改請求和響應消息的内容。HTTP 子產品是實作 IHttpModule 的類。 |
• | HTTP 句柄對象是 HTTP 請求的終結點,并為指定文類型提供請求處理。例如,一個句柄為 *.aspx 檔案處理請求的同時,另一個句柄為 *.asmx 檔案處理請求。HTTP 句柄生成并傳回 HTTP 響應消息。HTTP 句柄是實作 IHttpHandler 的類。 |
• | HttpContext 對象用于整個管道以代表目前的 Web 請求和響應。它适用于管道中的所有子產品和管道末端的句柄對象。HttpContext 對象公開多種屬性,包括 User 屬性,該屬性包含代表調用方的 IPrincipal 對象。 |
Web 請求剖析
ASP.NET ISAPI 庫 (Aspnet_isapi.dll) 運作在 IIS 程序位址空間 (Inetinfo.exe) 内。它将請求配置設定至 ASP.NET 輔助程序 (Aspnet_wp.exe) 中的 HttpRuntime 對象。為響應每個由 ASP.NET 接收的 Web 請求,出現以下操作集:
• | HttpRuntime 對象檢查請求并将其轉發到 HttpApplication 對象執行個體。 每個應用程式域(對象被彙集)至少有一個 HttpApplication 對象執行個體,每個 IIS 虛拟目錄至少有一個應用程式域。特定虛拟目錄中的初始檔案請求會建立新的應用程式域和新的 HttpApplication 對象。 |
• | 從 Machine.config (它們包含在 <HttpModules> 元素中)讀取 HTTP 子產品清單。可将附加的自定義 HTTP 子產品添加至指定應用程式的 Web.config。以下代碼片斷顯示了 Machine.config 内的預設 <HttpModules> 元素。 身份驗證子產品挂鈎 AuthenticateRequest 事件,而授權子產品挂鈎 AuthorizeRequest 事件。 請求通過管道中的每個子產品,盡管隻加載了單個身份驗證子產品。這取決于 Web.config 中 <authentication> 元素的配置。例如,加載跟随 WindowsAuthenticationModule 中結果的 <authentication> 元素。 |
• | 激活的身份驗證子產品負責建立 IPrincipal 對象并将其存儲在 HttpContext.User 屬性中。這非常重要,因為下遊的授權子產品使用這個 IPrincipal 對象來進行授權決定。 在沒有身份驗證的情況下(例如,在 IIS 内啟用匿名通路,并且 ASP.NET 配置為 ),會有特殊的非配置子產品将預設的匿名使用者放入 HttpContext. User 屬性中。是以,身份驗證後的 HttpContext.User 始終非空。 如果實施自定義身份驗證子產品,則自定義子產品中的代碼必須建立 IPrincipal 對象并将其存儲在 HttpContext.User 中。 注 ASP.NET 也根據 HttpContext.User 在 AuthenticateRequest 事件後限制 Thread.CurrentPrincipal。 |
• | HttpApplication 引發 AuthenticateRequest 事件(可在 global.asax 中挂鈎該事件)。這允許您插入自定義處理代碼,例如,加載與目前使用者關聯的角色集。但是,注意 WindowsAuthenticationModule 可自動完成該操作。角色清單從成員為經身份驗證的 Windows 使用者的 Windows 組集中擷取。 |
• | 适當的身份驗證子產品完成它的處理後,如果請求未被終止,則調用授權子產品。 |
• | 調用 UrlAuthorizationModule 時,它會檢查 Machine.config 和 Web.config 中的 <authorization> 頁籤。如果有,它将從 HttpContext.User 中檢索 IPrincipal 對象,并使用指定的謂詞(GET、POST 等)檢查是否授權使用者通路請求的資源。 如果沒有為使用者授權,則 UrlAuthorizationModule 調用 HttpApplication.CompleteRequest,終止正常的消息處理。 UrlAuthorizationModule 傳回 HTTP 401 狀态代碼。 |
• | 其次,将調用FileAuthorizationModule。它檢查 HttpContext.User.Identity 中的 IIdentity 對象是否是 WindowsIdentity 類的執行個體。 如果 IIdentity 對象不是 WindowsIdentity,則 FileAuthorizationModule 不再執行進一步的處理。 如果具有 WindowsIdentity,則 FileAuthorizationModule 調用 AccessCheck API(通過 P/Invoke)來檢視經身份驗證的調用方(其通路令牌已由 IIS 傳遞至 ASP.NET,并由 WindowsIdentity 對象公開)是否被授權通路請求的檔案。如果檔案的安全描述符在其 DACL 中包含至少一個 Read ACE,則允許請求繼續。否則,FileAuthorizationModule 調用 HttpApplication.CompleteRequest 并傳回 401 狀态代碼。 |
Forms 身份驗證處理
當以下元素位于 Web.config 中時,FormsAuthenticationModule 被激活。
<authentication mode="Forms" />
記住,對于 Forms 身份驗證,在 Global.asax 内執行 Application_Authenticate 事件。對于 Forms 身份驗證,會出現以下序列::
• | 在此代碼内,可構造 IPrincipal 對象并将其存儲在 HttpContext.User 中。這通常包括從自定義資料存儲區(通常為 SQL Server 資料庫或 Active Directory)檢索出的角色清單。IPrincipal 對象通常是 GenericPrincipal 類的執行個體,但也可以是自定義 IPrincipal 類。 FormsAuthenticationModule 檢查是否已建立 IPrincipal 對象。如果已建立,則由下遊的授權子產品來使用它。 如果沒有建立,則 FormsAuthenticationModule 構造一個 GenericPrincipal(沒有角色)并将其存儲在上下文中。 如果沒有角色資訊,任何請求角色成員的授權檢查(例如 PrincipalPermssion 請求)都将失敗。 |
• | UrlAuthorizationModule 處理 AuthorizeRequest 事件。它的授權決定基于 HttpContext.User 内的 IPrincipal 對象。 |
Windows 身份驗證處理
當以下元素位于 Web.config 内時, WindowsAuthenticationModule 被激活。
<authentication mode="Windows" />
對于 Windows 身份驗證,會出現以下序列:
1. | WindowsAuthenticationModule 使用由 IIS 傳遞至 ASP.NET 的 Windows 通路令牌建立 WindowsPrincipal 對象。 |
2. | 它使用 P/Invoke 來調用 Win32 函數以擷取使用者所屬的 Windows 組清單。這些用于填充 WindowsPrincipal 角色清單。 |
3. | 它将 WindowsPrincipal 對象存儲在 HttpContext.User 中,以備下遊的授權子產品使用。 |
事件處理
HttpApplication 對象引發表 1 中所示的事件集。單個 HTTP 子產品可挂鈎這些事件(通過提供它們自身的事件句柄)。
表 1:由 HttpApplication 對象引發的事件 | |
事件 | 說明 |
BeginRequest | 請求處理啟動前引發 |
AuthenticateRequest | 對調用方進行身份驗證 |
AuthorizeRequest | 執行通路檢查 |
ResolveRequestCache | 從緩存擷取響應 |
AcquireRequestState | 加載會話狀态 |
PreRequestHandlerExecute | 将請求發送至句柄對象前立即引發 |
PostRequestHandlerExecute | 将請求發送至句柄對象後立即引發 |
ReleaseRequestState | 存儲會話狀态 |
UpdateRequestCache | 更新響應緩存 |
EndRequest | 處理結束後引發 |
PreSendRequestHeaders | 發送經緩沖處理的響應頭前引發 |
PreSendRequestContent | 發送經緩沖處理的響應體前引發 |
注 HTTP 句柄在 PreRequestHandlerExecute 和PostRequestHandlerExecute 事件之間執行。
最後兩個事件具有不确定性,可在任何時間出現(例如,作為 Response.Flush 的結果)。其他所有事件均按順序出現。
無需隻為了挂鈎其中一個事件而執行 HTTP 子產品。也可向 Global.asax 添加事件句柄。除表 1 所列的事件(都可由單個 HTTP 子產品對象挂鈎)外,HttpApplication 對象還可引發 ASP 開發人員所熟悉的 Application_OnStart 和 Application_OnEnd 句柄。僅能夠在 Global.asax 内處理這些事件。最後,也可為由單個 HTTP 子產品對象引發的事件在 Global.asax 内執行自定義事件句柄。例如,會話狀态子產品引發 Session_OnStart 和 Session_OnEnd 事件。
執行自定義 HTTP 子產品
要建立自己的 HTTP 子產品并将其插入 ASP.NET 處理管道,請遵循以下步驟
1. | 建立實作 IHttpModule 的類。 |
2. | 将包含子產品的程式集放入應用程式的 /bin 子目錄下,或将其安裝到全局程式集緩存中。 |
3. | 将 <HttpModules> 元素添加到應用程式的 web.config,如下所示。 |
執行自定義 HTTP 句柄
您可能需要執行自定義 HTTP 句柄,例如,使用 .data 檔案擴充名進行檔案處理。
執行自定義 HTTP 句柄的步驟
1. | 向 IIS 中繼資料庫添加映射以将 .data 檔案擴充名映射到 ASP.NET ISAPI 擴充 (Aspnet_isapi.dll)。 在 IIS MMC 管理單元中用滑鼠右鍵單擊應用程式的虛拟目錄,再單擊 Configuration 按鈕,然後單擊 Add在 C:/Winnt/Microsoft.NET/Framework/v1.0.3705/aspnet_isapi.dll 下為 .data 檔案建立新映射。 注 如果在添加映射時選擇 Check that file exists 複選框,則檔案必須實際存在。除非已經虛拟化沒有映射到實體檔案的路徑,否則這通常是必需的要求。虛拟化路徑以由 .NET Remoting 使用的 .rem 或 .soap 結尾。 |
2. | 建立一個實作 IHttpHandler 的類(如果您想異步處理請求,可選擇建立 IHttpAsyncHandler)。 |
3. | 将包含句柄的程式集放入應用程式的 /bin 子目錄,或可将其安裝到全局程式集緩存中。 |
4. | 通過向應用程式的 Web.config 檔案添加 <httpHandlers> 節來向處理管道添加句柄。 |