ASP.NET 安全性

發佈日期: 09/30/2004 | 更新日期: 09/30/2004
pponline

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

Microsoft Corporation

*

本章內容

ASP.NET 是開發本指南所討論的分佈式 Web 應用程序的重心。它提供豐富而且容易訪問的安全能力級,從而方便了安全的 Web 應用程序的創建。ASP.NET 被設計成與 Internet Information Services (IIS) 的現有安全能力相兼容,但同時它也非常靈活,而且可以擴展。這意味着您可以構建與自己的應用程序緊密集成的自定義安全機制。

本章提供指南和建議來幫助您解決在構建安全的 ASP.NET Web 應用程序時碰到的身份驗證、授權和安全通信等問題。

本章所提供的大多數指南和建議同樣適用於開發 ASP.NET Web 服務和由 ASP.NET 託管的 .NET Remoting 對象。

目標

利用本章來:

保護您的 ASP.NET 應用程序。

保護由 ASP.NET 應用程序維護的機密和狀態信息。

理解 ASP.NET 應用程序的安全體系結構,並瞭解 IIS、Windows、.NET Framework 和ASP.NET 的安全能力如何協調工作,從而爲您的分佈式 Web 應用程序提供安全性。

選擇一種適合於您的應用程序的身份驗證和授權策略。

理解 ASP.NET 進程標識和模擬對您的應用程序訪問下游資源(如文件和數據庫)的能力的影響。

結合使用產品配置工具和編程技術來爲您的 ASP.NET Web 應用程序實現安全設計。

適用於

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

Microsoft® Windows® Server 2000 和 ™ 2003 操作系統

Microsoft Internet Information Services 5.0 和更高版本

Microsoft Active Directory® 目錄服務

Microsoft .NET Framework 1.0 版(帶 service pack 2)

Microsoft Visual Studio® 1.0 .NET 開發系統和更高版本

Microsoft Visual C#® .NET 開發工具

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

如何使用本章

要想從本單元獲得最大價值,您必須:

具有使用Visual C# .NET 和 Visual Studio .NET 進行編程的經驗。

具有開發和配置 ASP.NET Web 應用程序的經驗。

具有配置 IIS 安全性的經驗。

具有使用 Windows 管理工具配置 Windows 安全性和創建用戶帳號的經驗。

具有配置 Active Directory 的經驗。

具有開發和配置 Enterprise Services (COM+) 應用程序的經驗。

閱讀“Introduction”一章。它定義了身份驗證、授權和安全通信對分佈式 Web 應用程序的重要性。

閱讀“Security Model for ASP.NET Applications”一章。它概述了創建分佈式 ASP.NET Web 應用程序所使用的體系結構和技術,並着重指出該體系結構的什麼位置適用身份驗證、授權和安全通信。

閱讀“身份驗證和授權”一章。它介紹您在使用 ASP.NET 時可用的身份驗證和授權機制。

閱讀“Secure Communication”一章。它介紹可用於保護 ASP.NET 與分佈式 Web 應用程序之間的通信的各種技術。

閱讀以下各章,它們提供循序漸進的過程,爲您顯示如何實現本章所討論的許多技術:

How To Create a Custom Account to run ASP.NET

How To Set Up SSL on a Web Server

How To Use SSL to Secure Communication with SQL Server 2000

How To Use IPSec to Provide Secure Communication Between Two Servers

How To Implement IPrincipal

How To Use Forms Authentication with SQL Server 2000

How To Use Forms Authentication with Active Directory

How To Create GenericPrincipal Objects with Forms Authentication

How To Implement Kerberos Delegation for Windows 2000

本頁內容
ASP.NET 安全體系結構 ASP.NET 安全體系結構
身份驗證和授權策略 身份驗證和授權策略
配置安全性 配置安全性
編程安全性 編程安全性
Windows 身份驗證 Windows 身份驗證
窗體身份驗證 窗體身份驗證
無 Cookie 窗體身份驗證 無 Cookie 窗體身份驗證
更多信息 更多信息
Passport 身份驗證 Passport 身份驗證
自定義身份驗證 自定義身份驗證
ASP.NET 的進程標識 ASP.NET 的進程標識
模擬 模擬
訪問系統資源 訪問系統資源
訪問 COM 對象 訪問 COM 對象
訪問網絡資源 訪問網絡資源
安全通信 安全通信
存儲機密 存儲機密
保護會話和視圖狀態 保護會話和視圖狀態
網絡場注意事項 網絡場注意事項
小結 小結

ASP.NET 安全體系結構

ASP.NET 與 IIS、.NET Framework 和操作系統所提供的基礎安全服務配合使用,共同提供一系列身份驗證和授權機制。圖 1 總結了這些機制。

f08sn01

圖 1. ASP.NET 安全服務

圖 1 闡釋了 IIS 和 ASP.NET 所提供的身份驗證和授權機制。當客戶端發出 Web 請求時,就會發生以下一系列身份驗證和授權事件:

1.

接收來自網絡的 HTTP(S) Web 請求。可以使用 SSL 確保服務器身份(使用服務器證書)和客戶端身份(可選)的安全。

SSL 還提供了一個安全通道,以便保護在客戶端和服務器之間傳遞的機密數據。

2.

IIS 使用基本、簡要、集成(NTLM 或 Kerberos)或證書身份驗證方式驗證調用者的身份。如果站點的所有或部分內容不需要通過身份驗證即可訪問,則可將 IIS 配置爲使用匿名身份驗證。IIS 爲每個通過身份驗證的用戶創建一個 Windows 訪問令牌。如果選擇匿名身份驗證,則 IIS 爲該匿名 Internet 用戶帳號(默認爲 IUSR_MACHINE)創建訪問令牌。

3.

IIS 授權調用者訪問所請求的資源。使用附加到所請求資源的 ACL 定義的 NTFS 權限授權訪問。IIS 也可以配置爲只接受來自特定 IP 地址的客戶端計算機的請求。

4.

IIS 將通過身份驗證的調用者的 Windows 訪問令牌傳遞給 ASP.NET (如果使用匿名身份驗證,則它可能是匿名 Internet 用戶的訪問令牌)。

5.

ASP.NET 驗證調用者的身份。

如果 ASP.NET 配置爲使用 Windows 身份驗證,則此時不會發生任何其他的身份驗證。ASP.NET 將接受它從 IIS 接收的任何令牌。

如果 ASP.NET 配置爲使用窗體身份驗證,則將根據數據存儲(通常爲 SQL Server 數據庫或 Active Directory 目錄服務)對調用者提供的憑證進行身份驗證(使用 HTML 窗體)。如果 ASP.NET 配置爲使用 Passport 身份驗證,則將用戶重定向到 Passport 站點,然後 Passport 身份驗證服務對用戶進行身份驗證。

6.

ASP.NET 授權訪問所請求的資源或操作。

UrlAuthorizationModule(系統提供的 HTTP 模塊)使用在 Web.config 中配置的授權規則(具體來講就是 <authorization> 元素),確保調用者可以訪問所請求的文件或文件夾。

在 Windows 身份驗證下,FileAuthorizationModule(另一個 HTTP 模塊)會檢查調用者是否具有訪問所請求資源的必要權限。將調用者的訪問令牌與保護資源的 ACL 進行比較。

也可以使用 .NET 角色(以聲明方式或編程方式)確保調用者被授權訪問所請求的資源或執行所請求的操作。

7.

應用程序中的代碼使用特定標識來訪問本地和/或遠程資源。默認情況下,ASP.NET 不執行模擬,因此,由配置好了的 ASP.NET 進程帳號提供標識。也可以選擇原調用者的標識(如果啓用了模擬)或已配置的服務標識。

網關守衛

ASP.NET Web 應用程序中的授權點或網關守衛是由 IIS 和 ASP.NET 提供的:

IIS

如果關閉了匿名身份驗證,則 IIS 只允許來自特定用戶的請求,即它可以在其自己的域或受信任域中驗證這些用戶的身份。

對於靜態文件類型(例如 .jpg、.gif 和 .htm 文件,即沒有映射到 ISAPI 擴展的文件),IIS 使用與所請求的文件相關的 NTFS 權限來執行訪問控制。

ASP.NET

ASP.NET 網關守衛包括 UrlAuthorizationModuleFileAuthorizationModule 和主體權限要求和角色檢查。

UrlAuthorizationModule

可以配置應用程序 Web.config 文件中的 <authorization> 元素來控制哪些用戶和用戶組可以訪問應用程序。授權是基於存儲在 HttpContext.User 中的 IPrincipal 對象進行的。

FileAuthorizationModule

對於被 IIS 映射到 ASP.NET ISAPI 擴展(Aspnet_isapi.dll) 的文件類型,使用已驗證用戶的 Windows 訪問令牌(可能是 IUSR_MACHINE),根據附加到所請求的 ASP.NET 文件的 ACL 自動執行訪問檢查。

要進行文件授權,並不要求模擬。

FileAuthorizationModule 類只對所請求的文件執行訪問檢查,而不對所請求的頁面中的代碼所訪問的文件執行訪問檢查,但 IIS 對這些文件執行訪問檢查。

例如,如果您請求 Default.aspx,並且它包含一個嵌入的用戶控件(Usercontrol.ascx),而該控件又包含一個圖像標籤(指向 Image.gif),則 FileAuthorizationModule 會對 Default.aspx 和 Usercontrol.ascx 執行訪問檢查,因爲 IIS 將這些文件類型映射到 ASP.NET ISAPI 擴展。

FileAuthorizationModule 不對 Image.gif 執行訪問檢查,因爲它是由 IIS 內部處理的靜態文件。然而,由於 IIS 對靜態文件執行訪問檢查,所以仍然使用進行相應配置的 ACL 對已驗證用戶授予讀取該文件的權限。

圖 2 顯示了此方案。

對於系統管理員:需要給已通過身份驗證的用戶授予讀取此方案中涉及的所有文件的 NTFS 權限。惟一的變化是使用哪個網關守衛來執行訪問控制。ASP.NET 進程帳號只需要讀取 ASP.NET 註冊文件類型的訪問權限。

f08sn02

圖 2. IIS 和 ASP.NET 網關守衛一起使用

在此方案中,您可以在文件入口處禁止訪問。如果您配置了附加到 Default.aspx 的 ACL,並且拒絕訪問某個特定的用戶,則 Default.aspx 中的代碼無法將用戶控件或任何嵌入圖像發送到客戶端。如果該用戶直接請求圖像,則 IIS 親自執行訪問檢查。

主體權限要求和明確的角色檢查

除了可以用 IIS 和 ASP.NET 配置的網關守衛外,還可以將主體權限要求(以聲明方式或編程方式)用作附加的細分訪問控制機制。通過使用主體權限檢查(由 PrincipalPermissionAttribute 類執行),您可以根據各個用戶的標識和組成員身份(由附加到當前線程的 IPrincipal 對象定義)控制訪問類、方法或個別代碼塊。

用於請求角色成員身份的主體權限要求與調用 IPrincipal.IsInRole 來測試角色成員身份不同;如果調用者不是指定角色的成員,則前者產生異常,而後者僅返回一個布爾值來確認角色成員身份。

在 Windows 身份驗證中,ASP.NET 自動將一個代表已驗證身份用戶的 WindowsPrincipal 對象連接到當前的 Web 請求(使用 HttpContext.User)。窗體和 Passport 身份驗證創建具有相應標識但沒有角色的 GenericPrincipal 對象,並將它附加到 HttpContext.User

更多信息

有關配置安全性的詳細信息,請參見本章後面的“配置安全性”。

有關編程安全性(和 IPrincipal 對象)的詳細信息,請參見本章後面的“編程安全性”。

身份驗證和授權策略

ASP.NET 提供了若干以聲明方式和編程方式進行授權的機制,這些機制可與各種身份驗證方案配合使用。這樣,您就可以開發深入的授權策略以及可以配置爲提供各種粒度級別(例如,基於角色的每用戶或每用戶組)的授權策略。

本節說明一組常用身份驗證選項的可用授權選項(可進行配置和編程)。

下面概述了身份驗證選項:

帶模擬的 Windows 身份驗證

不帶模擬的 Windows 身份驗證

使用固定身份的 Windows 身份驗證

窗體身份驗證

Passport 身份驗證

可用的授權選項

下表列出了一組可用的授權選項。對於每個選項,該表都指出是否需要 Windows 身份驗證和/或模擬。如果特定授權選項不需要 Windows 身份驗證,則該選項適用於所有其他的身份驗證類型。可以使用該表優化身份驗證/授權策略。

表 1:Windows 身份驗證和模擬要求
授權選項 需要 Windows 身份驗證 需要模擬

FileAuthorizationModule

UrlAuthorizationModule

Principal Permission Demands

.NET Roles

Enterprise Services Roles

是(在 ASP.NET Web 應用程序中)

NTFS 權限(用於直接請求的靜態文件類型;沒有映射到 ISAPI 擴展的文件類型)

不適用— ASP.NET 不處理這些文件。
在任何(非匿名)IIS 身份驗證機制中,應爲各個已驗證的用戶配置權限。
在匿名身份驗證中,應爲 IUSR_MACHINE 配置權限。

否(IIS 執行訪問檢查。)

NTFS 權限(用於 Web 應用程序代碼訪問的文件)


如果使用模擬,請根據模擬的 Windows 標識配置 ACL,該標識可以是原調用者,也可以是 Web.config 中的 <identity> 元素指定的標識。

帶模擬的 Windows 身份驗證

以下配置元素顯示瞭如何明確啓用 Web.config 或 Machine.config中的 Windows (IIS) 身份驗證和模擬。

應根據每個應用程序的具體情況,在應用程序的 Web.config 文件中配置身份驗證。

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

在此配置中,ASP.NET 應用程序代碼模擬已由 IIS 驗證身份的調用者。

可配置的安全性

當您將 Windows 身份驗證和模擬功能一起使用時,就可以使用下列授權選項:

WindowsACLs

客戶端請求的資源。ASP.NET FileAuthorizationModule 對映射到 ASP.NET ISAPI 的請求文件類型執行訪問檢查。它使用原調用者的訪問令牌和附加到請求資源的 ACL 以便執行訪問檢查。

對於靜態文件類型(沒有映射到 ISAPI 擴展),IIS 使用調用者的訪問令牌和附加到文件的 ACL 執行訪問檢查。

應用程序訪問的資源。可以根據原調用者,在應用程序訪問的資源(文件、文件夾、註冊表項和 Active Directory 對象等)上配置 Windows ACL。

URL 授權。在 Web.config 中配置 URL 授權。在 Windows 身份驗證中,用戶名採用 DomainName/UserName 的格式,並且角色與 Windows 組 一 對應。

<authorization>
  <deny user="DomainName/UserName" />
  <allow roles="DomainName/WindowsGroup" />
</authorization>

Enterprise Services (COM+) 角色。角色保存在 COM+ 目錄中。可以使用“組件服務”管理工具或腳本配置角色。

編程安全性

編程安全性是指 Web 應用程序代碼中的安全檢查。在您使用 Windows 身份驗證和模擬功能時,可以使用下列程序安全設置選項:

PrincipalPermission 請求

命令性(嵌入方法的代碼內)

PrincipalPermission permCheck = new PrincipalPermission(
                                       null, @"DomainName/WindowsGroup");
    permCheck.Demand();

聲明性(屬性位於接口、類和方法之前)

[PrincipalPermission(SecurityAction.Demand, 
                  Role=@"DomainName/WindowsGroup)]

明確的角色檢查。您可以使用 IPrincipal 接口執行角色檢查。

IPrincipal.IsInRole(@"DomainName/WindowsGroup");

Enterprise Services (COM+) 角色。可以使用 ContextUtil 類以編程方式執行角色檢查。

ContextUtil.IsCallerInRole("Manager")

何時使用

使用 Windows 身份驗證和模擬的情況:

應用程序的用戶已經有了可以由服務器驗證的 Windows 帳號。

您需要將原調用者的安全性上下文傳遞到 Web 應用程序的中間層和/或數據層以支持細分(每用戶)授權。

您需要將原調用者的安全性上下文傳遞到下游各層以支持操作系統級審覈。

在應用程序中使用模擬之前,確保將此方法與使用受信任的子系統模型進行比較,瞭解此方法的優缺點。“身份驗證和授權”一章中的“授權方式”章節中的“選擇資源訪問模式”詳細闡述了這些內容。

模擬的缺點包括:

由於無法對數據庫連接進行池處理,因而降低了應用程序的可擴展性。

由於需要給各個用戶配置後端資源的 ACL,因而增加了管理工作。

委派需要 Kerberos 身份驗證和進行適當配置的環境。

更多信息

有關 Windows 身份驗證的詳細信息,請參見本章後面的“Windows 身份驗證”。

有關模擬的詳細信息,請參見本章後面的“模擬”。

有關 URL 授權的詳細信息,請參見本章後面的“URL 授權注意事項”。

有關 Enterprise Services (COM+) 角色的詳細信息,請參見“Enterprise Services Security一章。

不帶模擬的 Windows 身份驗證

下列配置元素顯示瞭如何在Web.config.中明確聲明啓用不帶模擬功能的 Windows(IIS) 身份驗證。

<authentication mode="Windows" />
<!-- The following setting is equivalent to having no identity element -->
<identity impersonate="false" />

可配置的安全性

當您使用不帶模擬的 Windows 身份驗證時,可以使用以下授權選項:

WindowsACL

客戶端請求的資源。ASP.NET FileAuthorizationModule 對映射到 ASP.NET ISAPI 的請求文件類型執行訪問檢查。它使用原調用者的訪問令牌和附加到請求資源的 ACL 以便執行訪問檢查。模擬不是必需選項。

對於靜態文件類型(沒有映射到 ISAPI 擴展),IIS 使用調用者的訪問令牌和附加到文件的 ACL 執行訪問檢查。

應用程序訪問的資源。根據 ASP.NET 進程標識,在應用程序所訪問的資源(文件、文件夾、註冊表項和 Active Directory 對象)上配置 Windows ACL。

URL 授權。在 Web.config 中配置 URL 授權。在 Windows 身份驗證中,用戶名採用 DomainName/UserName 格式,並且角色與 Windows 組 一 對應。

<authorization>
  <deny user="DomainName/UserName" />
  <allow roles="DomainName/WindowsGroup" />
</authorization>

程序安全性

可以使用下列編程安全選項:

主體權限要求

命令性

PrincipalPermission permCheck = new PrincipalPermission(
                                         null, @"DomainName/WindowsGroup");
    permCheck.Demand();

聲明性

[PrincipalPermission(SecurityAction.Demand, 
                  Role=@"DomainName/WindowsGroup")]

明確的角色檢查。您可以使用IPrincipal 接口執行角色檢查。

IPrincipal.IsInRole(@"DomainName/WindowsGroup");

何時使用

使用不帶模擬的 Windows 身份驗證的情況:

應用程序的用戶已經有了可以由服務器驗證的 Windows 帳戶。

需要使用固定標識來訪問下游資源(例如數據庫)以便支持連接池。

更多信息

有關 Windows 身份驗證的詳細信息,請參見本章後面的“Windows 身份驗證”。

有關 URL 授權的詳細信息,請參見本章後面的“URL 授權注意事項”。

使用固定標識的 Windows 身份驗證

Web.config 中的 <identity> 元素支持可選的用戶名和密碼屬性,這樣,您就可以爲應用程序配置特定的固定標識以進行模擬。這顯示在以下配置文件片段中。

<identity impersonate="true"
          userName="registry:HKLM/SOFTWARE/YourSecureApp/
                    identity/ASPNET_SETREG,userName"
          password="registry:HKLM/SOFTWARE/YourSecureApp/
                    identity/ASPNET_SETREG,password" />

這個例子顯示了 <identity> 元素,其中憑證在註冊表中使用 aspnet_setreg.exe 工具進行加密。明文形式的 userNamepassword 屬性值被指向安全的註冊表項和包含加密憑證的命名值的指針所替代。有關這個工具的詳細信息及下載方式,請參見 Microsoft 知識庫中的文件 Q329290 “HOWTO:Use the ASP.NET Utility to Encrypt Credentials and Session State Connection Strings”。

何時使用

當在運行 Windows 2000 的服務器上使用 .NET Framework 1.0 時,不建議使用固定的模擬標識。因爲這需要您授予 ASP.NET 進程帳戶“充當操作系統的一部分”權限,這個權限很大。 ASP.NET 進程需要這個權限,因爲它使用您所提供的憑證執行 LogonUser 調用。

.NET 框架 1.1 版將在 Windows 2000 上提供此方案的改進版本。憑證將由 IIS 進程執行,這樣 ASP.NET 就不需要“充當操作系統的一部分”權限了。

窗體身份驗證

以下配置元素顯示瞭如何在 Web.config 中以聲明方式啓用窗體身份驗證。

<authentication mode="Forms">
  <forms loginUrl="logon.aspx" name="AuthCookie" timeout="60" path="/">
  </forms>
</authentication>

可配置的安全性

在使用窗體身份驗證時,可以使用以下授權選項:

WindowsACL

客戶端請求的資源。請求的資源需要 ACL 以允許對匿名 Internet 用戶帳戶進行讀取訪問。(在使用窗體身份驗證時,應該將 IIS 配置爲允許匿名訪問)。

無法使用 ASP.NET 文件授權,因爲它需要 Windows 身份驗證。

應用程序訪問的資源。根據 ASP.NET 進程標識,在應用程序所訪問的資源(文件、文件夾、註冊表項和 Active Directory 對象)上配置 Windows ACL。

URL 授權

在 Web.config 中配置 URL 授權。在窗體身份驗證中,用戶名的格式取決於自定義數據存儲、SQL Server 數據庫或 Active Directory。

如果使用的是 SQL Server 數據存儲,則爲:

<authorization>
<deny users="?" />
  <allow users="Mary,Bob,Joe" roles="Manager,Sales" />
</authorization>

如果使用 Active Directory 作爲數據存儲,則以 X.500 格式顯示用戶名和組名:

<authorization>
  <deny users="[email protected]" />
  <allow roles ="CN=Smith James,CN=FTE_northamerica,CN=Users,
                DC=domain,DC=corp,DC=yourCompany,DC=com" />
</authorization>

程序安全性

可以使用下列編程安全選項:

主體權限要求

命令性

PrincipalPermission permCheck = new PrincipalPermission(
                                         null, "Manager");
    permCheck.Demand();

聲明性

[PrincipalPermission(SecurityAction.Demand, 
                  Role="Manager")]

明確的角色檢查。您可以使用 IPrincipal 接口執行角色檢查。

IPrincipal.IsInRole("Manager");

何時使用

窗體身份驗證最適合於 Internet 應用程序。如果出現以下情況,則應該使用窗體身份驗證:

應用程序用戶沒有 Windows 帳戶。

您希望用戶通過使用 HTML 窗體輸入憑證的方式登錄到應用程序。

更多信息

有關窗體身份驗證的詳細信息,請參見本章後面的“窗體身份驗證“。

有關 URL 授權的詳細信息,請參見本章後面的“URL 授權注意事項”。

Passport 身份驗證

以下配置元素顯示瞭如何在 Web.config 中以聲明方式啓用 Passport 身份驗證。

<authentication mode="Passport" />

何時使用

如果應用程序用戶沒有 Windows 帳戶,並且您希望實現單次登錄解決方案,則應該在 Internet 上使用 Passport 身份驗證。如果用戶以前使用 Passport 帳戶在參與的 Passport 站點進行登錄,則不必登錄到使用 Passport 身份驗證配置的站點。

配置安全性

本節說明配置 ASP.NET Web 應用程序安全性所需的實際步驟。 3 總結了這些情況。

F08sn03_t

3. 配置 ASP.NET 應用程序安全性

配置 IIS 設置

要配置 IIS 安全性,您必須執行以下步驟:

1.

(可選)安裝 Web 服務器證書(如果需要 SSL 的話)。 有關詳細信息,請參見“How To Set Up SSL on a Web Server”。

2.

配置 IIS 身份驗證。

3.

(可選)配置客戶端證書映射(如果使用證書身份驗證的話)。

有關客戶端證書映射的詳細信息,請參見 Microsoft 知識庫文章 Q313070“How To:Configure Client Certificate Mappings in Internet Information Services (IIS) 5.0”。

4.

設置文件和文件夾的 NTFS 權限。IIS 和 ASP.NET FileAuthorizationModule 共同檢查已驗證用戶(或匿名 Internet 用戶帳戶)是否具有訪問所請求文件的必要權限(根據 ACL 設置)。

配置 ASP.NET 設置

應用程序級別配置設置保存在 Web.config 文件中,這些文件位於應用程序的虛擬根目錄或者(可選)其他子文件夾中(這些設置有時可以覆蓋父文件夾設置)。

1.

配置身份驗證。應該在應用程序虛擬根目錄下的 Web.config 文件中基於每個應用程序對它進行設置(而不是在 Machine.config 中)。

<authentication mode="Windows|Forms|Passport|None" />

2.

配置模擬。默認情況下,ASP.NET 應用程序不使用模擬。應用程序使用配置的 ASP.NET 進程標識(通常爲 ASPNET)運行,並且應用程序執行的所有資源訪問都使用此標識。僅在以下情況下需要使用模擬:

您使用 Enterprise Services,並且要使用 Enterprise Services (COM+) 角色授權訪問服務組件所提供的功能。

將 IIS 配置爲使用匿名身份驗證,而且要使用匿名 Internet 用戶帳戶進行資源訪問。有關此方法的詳細信息,請參見本章後面的“訪問網絡資源”。

您需要將已驗證用戶的安全性上下文傳遞到下一層(例如數據庫)。

您已將傳統的 ASP 應用程序移植到 ASP.NET,並且需要同樣的模擬行爲。默認情況下,傳統 ASP 模擬調用者。

要配置 ASP.NET 模擬,請在應用程序的 Web.config 中使用下面的 <identity> 元素。

<identity impersonate="true" />

3.

配置授權。URL 授權確定用戶或角色是否可以將特定的 HTTP 謂詞(例如,GET、HEAD 和 POST)發送給特定的文件。要實現 URL 授權,請執行以下任務。

1.

將 <authorization> 元素添加到應用程序虛擬根目錄下的 Web.config 文件中。

2.

使用 allowdeny 屬性限制對用戶和角色的訪問。下面的示例摘自 Web.config,它使用 Windows 身份驗證並允許 Bob 和 Mary 訪問,但拒絕其他人訪問。

<authorization>
  <allow users="DomainName/Bob, DomainName/Mary" />
  <deny users="*" />
</authorization>

重要 您需要在 <authorization> 元素的結尾添加 <denyusers="?"> 或 <denyusers="*">,否則將給所有已驗證的標識授予訪問權限。

URL 授權注意事項

在配置 URL 授權時,請注意以下幾點:

"*" 指所有標識。

"?" 指未通過身份驗證的標識(即匿名標識)。

要使 URL 授權能夠正常工作,並不需要進行模擬。

Web.config 中的授權設置通常適用於當前目錄和所有子目錄中的所有文件(除非子目錄包含它自己的 Web.config,並且該文件包含 <authorization> 元素。在這種情況下,子目錄中的設置覆蓋父目錄的設置)。

URL 授權只適用於由 IIS 映射到 ASP.NET ISAPI (spnet_isapi.dll) 的文件類型。

可以使用 <location> 標記將授權設置應用於個別文件或目錄。下面的示例顯示瞭如何將授權應用於特定的文件 (Page.aspx)。

<location path="page.aspx" />
  <authorization>
    <allow users="DomainName/Bob, DomainName/Mary" />
    <deny users="*" />
  </authorization>
</location>

用於 URL 授權的用戶和角色是由身份驗證設置決定的:

如果設置了 <authenticationmode="Windows" >,則給 Windows 用戶和組帳戶授予訪問權限。 用戶名採用“DomainName/WindowsUserName”格式 角色名採用“DomainName/WindowsGroupName”格式

本地管理員組稱爲“BUILTIN/Administrators”。本地用戶組稱爲“BUILTIN/Users”。

如果設置了 <authenticationmode="Forms" >,則根據存儲在當前 HTTP 上下文中的 IPrincipal 對象的用戶和角色進行授權。例如,如果使用窗體身份驗證根據數據庫驗證用戶的身份,則根據從數據庫中檢索的角色進行授權。

如果設置了 <authenticationmode="Passport" >,則根據從存儲中檢索的 Passport User ID (PUID) 或角色進行授權。例如,可以將 PUID 映射到特定的帳戶和在 SQL Server 數據庫或 Active Directory 中存儲的一組角色。

此功能被內置到 Microsoft Windows .NET Server 2003 操作系統中。

如果設置了 <authenticationmode="None" >,則不能執行授權。"None" 指定您不想執行任何身份驗證,或者不想使用任何 .NET 身份驗證模塊,而是使用自己的自定義機制。

但是,如果使用自定義身份驗證,則應創建具有角色的 IPrincipal 對象,並將其存儲到 HttpContext.User 中。在隨後執行 URL 授權時,將根據 IPrincipal 對象中保存的用戶和角色(無論以何種方式檢索它們)執行授權。

URL 授權示例

以下列表列出了一些典型 URL 授權示例的語法:

拒絕匿名帳戶訪問

<deny users="?" />

拒絕所有用戶訪問

<deny users="*"/>

拒絕 Manager 角色訪問

<deny roles="Manager"/>

窗體身份驗證示例

<configuration>
  <system.web>
      <authentication mode="Forms">
        <forms name=".ASPXUSERDEMO" 
               loginUrl="login.aspx" 
               protection="All" timeout="60" />
      </authentication>
      <authorization>
        <deny users="[email protected]" />
        <deny users="?" />
      </authorization>
  </system.web>
</configuration>

<authorization> 元素可用於存儲在 HttpContext.User 中的當前 IPrincipal 對象,也可用於存儲在 HttpContext.Request.RequestType 中的 HTTP 數據傳輸方法。

保護資源

1.

使用 Windows ACL 保護資源,包括文件、文件夾和註冊表項。

如果不使用模擬,則應用程序需要訪問的任何資源的 ACL 必須授予 ASP.NET 進程帳戶至少“讀”訪問權限。

如果使用模擬,文件和註冊表項的 ACL 必須授予已驗證用戶(或匿名 Internet 用戶帳戶,如果匿名身份驗證生效的話)至少“讀”訪問權限。

2.

保護 Web.config 和 Machine.config:

使用正確的 ACL。如果 ASP.NET 使用模擬,則模擬的標識需要“讀”訪問權限。否則,ASP.NET 進行標識需要“讀”訪問權限。對 Web.config 的 Machine.config 使用以下 ACL。

系統:完全控制

管理員:完全控制

進程標識或模擬的標識:讀

如果沒有模擬匿名 Internet 用戶帳戶 (IUSR_MACHINE),則應該拒絕該帳戶的訪問。

如果將應用程序映射到 UNC 共享,則 UNC 標識也需要讀取配置文件的訪問權限。

刪除不需要的 HTTP 模擬。Machine.config 包含一組默認的 HTTP 模擬(在 <httpModules> 元素內)。它們是:

WindowsAuthenticationModule

FormsAuthenticationModule

PassportAuthenticationModule

UrlAuthorizationModule

FileAuthorizationModule

OutputCacheModule

SessionStateModule

如果應用程序沒有使用特定的模擬,請將其刪除,以免將來在應用程序中出現與該模擬有關的任何潛在的安全問題。

3.

(可選)將 <location> 元素與 allowOverride="false" 屬性一起使用以鎖定配置設置,如下所示。

鎖定配置設置

配置設置是分層的。子目錄中的 Web.config 文件設置覆蓋父目錄中的 Web.config 設置。另外,Web.config 設置覆蓋 Machine.config 設置。

通過將 <location> 元素與 allowOverride 屬性一起使用,可以鎖定配置設置以防止它們被低級別的設置覆蓋。例如:

<location path="somepath" allowOverride="false" />
 . . . arbitrary configuration settings . . .
</location>

請注意:路徑可以指 Web 站點或虛擬目錄,並且它適用於指定的目錄和所有子目錄。如果將 allowOverride 設置爲 false,則可以防止任何低級別的配置文件覆蓋 <location> 元素中指定的位置。鎖定配置設置的功能適用於所有設置類型,而不僅限於安全設置(如身份驗證模式)。

在 machine.config 的上下文中,路徑必須爲全資格的,並且包含 Web 站點、虛擬目錄名稱和(可選)一個子目錄和文件名。例如:

<location path="Web Site Name/VDirName/SubDirName/PageName.aspx" >
 . . .
</location>

在 Web.config 的上下文中,路徑只與應用程序的虛擬目錄有關。例如:

<location path="SubDirName/PageName.aspx" >
. . .
</location>

禁止下載文件

可以使用 HttpForbiddenHandler 類禁止通過 Web 下載某些文件類型。該類由 ASP.NET 在內部使用以禁止下載某些系統級文件(例如,包括 Web.config 在內的配置文件)。有關以這種方式進行限制的文件類型的完整列表,請參見 machine.config 中的 <httpHandlers> 部分。

對於應用程序在內部使用但不能進行下載的文件,應考慮使用 HttpForbiddenHandler

還必須使用 Windows ACL 來保護文件,控制哪些用戶在登錄到 Web 服務器上時可以訪問這些文件。

使用 HttpForbiddenHandler 禁止下載特定的文件類型

1.

在 IIS 中爲指定的文件類型創建應用程序映射,以便將其映射到 Aspnet_isapi.dll。

1.

在任務欄上,依次單擊“開始”按鈕、單擊“程序”,單擊“管理工具”然後選擇“Internet 信息服務”。

2.

選擇應用程序的虛擬目錄,右擊,然後單擊“屬性”。

3.

選擇“應用程序設置”,然後單擊“配置”。

4.

單擊“添加”以創建新的應用程序映射。

5.

單擊“瀏覽”,然後選擇c:/winnt/Microsoft.NET/Framework/v1.0.3705/aspnet_isapi.dll。

6.

在“擴展”字段中鍵入要禁止下載的文件類型的擴展名(例如,.abc)。

7.

確保選中“所有版本”和“腳本引擎”,並且不選擇“該文件是否存在”。

8.

單擊 OK 關閉“添加/編輯應用程序擴展映射”對話框。

9.

單擊 OK 關閉“應用程序配置”對話框,然後再單擊 OK 關閉“屬性”對話框。

2.

在 Web.config 中,爲指定的文件類型添加 <HttpHandler> 映射。

下面顯示了一個 .abc 文件類型的示例。

<httpHandlers>
  <add verb="*" path="*.abc" 
    type="System.Web.HttpForbiddenHandler"/>
</httpHandlers>

安全通信

結合使用 SSL 和 Internet 協議安全 (IPSec) 以保護通信鏈路。

更多信息

有關使用 SSL 保護數據庫服務器鏈路的信息,請參見“How To Use SSL to Secure Communication with SQL Server 2000”。

有關在兩臺計算機之間使用 IPSec 的信息,請參見“How To Use IPSec to Provide Secure Communication Between Two Servers”。

編程安全性

在確定 Web 應用程序可配置的安全設置後,您需要以編程方式進一步改進和優化應用程序的授權策略。這包括在程序集中使用聲明性的 .NET 屬性,以及在代碼中執行命令性的授權檢查。

本節重點介紹在 ASP.NET Web 應用程序中執行授權所需的主要編程步驟。

授權模式

下面總結了在 Web 應用程序中對用戶進行授權的基本模式:

1.

檢索憑證

2.

檢驗憑證

3.

將用戶放到角色中

4.

創建一個 IPrincipal 對象

5.

IPrincipal 對象放到當前的 HTTP 上下文中

6.

基於用戶標識/角色成員身份進行授權

重要 如果配置了 Windows 身份驗證,則 ASP.NET 自動執行步驟 1 到 5。對於其他身份驗證機制(窗體、Passport 和自定義方法),您必須編寫代碼以執行這些步驟(如下所示)。

檢索憑證

首先,必須從用戶檢索一組憑證(用戶名和密碼)。如果應用程序沒有使用 Windows 身份驗證,則需要確保使用 SSL 在網絡上正確保護明文憑證。

檢驗憑證

如果配置了 Windows 身份驗證,則操作系統的基本服務就會自動對憑證進行檢驗。

如果使用其他身份驗證機制,則必須編寫代碼以根據數據存儲(如 SQL Server 數據庫或 Active Directory)對憑證進行檢驗。

有關如何將用戶憑證安全地存儲在 SQL Server 數據庫中的詳細信息,請參見“數據訪問安全性”一章中的“對數據庫進行用戶身份驗證”。

將用戶放到角色中

用戶數據存儲還應包含每個用戶的角色列表。必須編寫代碼以檢索已檢驗用戶的角色列表。

創建一個 IPrincipal 對象

授權是針對已驗證用戶進行的,這些用戶的標識和角色列表保存在 IPrincipal 對象中(該對象在當前 Web 請求的上下文中傳遞)。

如果配置了 Windows 身份驗證,則 ASP.NET 會自動構造 WindowsPrincipal 對象。該對象包含已驗證用戶的標識以及角色列表(它等同於用戶所屬的 Windows 組列表)。

如果使用的是窗體、Passport 或自定義身份驗證,則必須在 Global.asax 的 Application_AuthenticateRequest 事件處理程序中編寫代碼以創建 IPrincipal 對象。GenericPrincipal 類是由 .NET 框架提供的,在大多數情況下應該使用此類。

將 IPrincipal 對象放到當前 HTTP 上下文中

IPrincipal 對象附加到當前 HTTP 上下文中(使用 HttpContext.User 變量)。如果使用 Windows 身份驗證,則 ASP.NET 自動完成此任務。否則,您必須手動附加該對象。

基於用戶標識和/或角色成員身份進行授權

如果應用程序需要更細分的授權邏輯,請在代碼中以聲明方式(獲取類或方法級授權)或命令性方式使用 .NET 角色。

可以使用聲明性或命令性主體權限要求(使用 PrincipalPermission 類),也 可以通過調用 IPrincipal.IsInRole() 方法執行明確的角色檢查。

以下示例採用 Windows 身份驗證並顯示了聲明性主體權限要求。僅當已驗證用戶是 Manager Windows 組的成員時,才執行該屬性後面的方法。如果調用者不是該組的成員,就會發生 SecurityException

[PrincipalPermission(SecurityAction.Demand, 
                     Role=@"DomainName/Manager")]
public void SomeMethod()
{
}

以下示例顯示代碼中的明確角色檢查。該示例採用 Windows 身份驗證。如果使用非 Windows 身份驗證機制,則代碼基本上是一樣的。只是將 User 對象轉換成 WindowsPrincipal 對象,而不是 GenericPrincipal 對象。

// Extract the authenticated user from the current HTTP context.
// The User variable is equivalent to HttpContext.Current.User if you are using // an .aspx or .asmx page
WindowsPrincipal authenticatedUser = User as WindowsPrincipal;
if (null != authenticatedUser)
{
  // Note: To retrieve the authenticated user's username, use the 
  // following line of code
  // string username = authenticatedUser.Identity.Name;

  // Perform a role check
  if (authenticatedUser.IsInRole(@"DomainName/Manager") )
  {
    // User is authorized to perform manager functionality
  }
}
else
{
  // User is not authorized to perform manager functionality
}

更多信息

有關以上窗體身份驗證模式的實現實現,請參見本章後面的“窗體身份驗證”部分。

創建自定義的 IPrincipal 類

當您使用非 Windows 身份驗證機制時,大多數情況下應使用 .NET 框架提供的 GenericPrincipal 類。它使用 IPrincipal.IsInRole 方法提供角色檢查。

有時,您可能需要實現自己的 IPrincipal 類。實現您自己的 IPrincipal 的原因有:

您想擴展角色檢查功能。您可能需要一些方法來使您能夠檢查某個特定用戶是否是一個多角色成員。例如:

CustomPrincipal.IsInAllRoles( "Role", "Role2", "Role3" )
CustomPrincipal.IsInAnyRole( "Role1", "Role2", "Role3" )

您可能需要實現一個額外的方法或屬性,以數組形式返回角色列表。例如:

string[] roles = CustomPrincipal.Roles;

您想讓應用程序強制實施角色分級邏輯。例如,高級管理員被認爲在層次結構中高於普通管理員。可以用類似下面所示的方法進行測試。

CustomPrincipal.IsInHigherRole("Manager");
CustomPrincipal.IsInLowerRole("Manager");

您可能需要實現惰性的角色列表初始化。例如,只有在需要進行角色檢查時,才能動態加載角色列表。 您可能需要實現 IIdentity 接口以使用 X509ClientCertificate 標識的用戶。例如:

CustomIdentity id = CustomPrincipal.Identity;
X509ClientCertificate cert = id.ClientCertificate;

更多信息

有關創建您自己的 IPrincipal 類的詳細信息,請參見“How To Implement IPrincipal”。

Windows 身份驗證

如果應用程序用戶使用可由服務器進行身份驗證的 Windows 帳戶(例如,在 Intranet 方案中),請使用 Windows 身份驗證。

如果將 ASP.NET 配置爲使用 Windows 身份驗證,則 IIS 使用配置的 IIS 身份驗證機制執行用戶身份驗證。 4 顯示了這種情況。

f08sn04

4. ASP.NET Windows 身份驗證使用 IIS 驗證調用者的身份

已驗證調用方(如果將 IIS 配置爲使用匿名身份驗證,則它可能是匿名 Internet 用戶帳戶)的訪問令牌可供 ASP.NET 應用程序使用。請注意以下方面:

這將允許 ASP.NET FileAuthorizationModule 使用原調用者的訪問令牌,對請求的 ASP.NET 文件執行訪問檢查。

重要 ASP.NET 文件授權只對映射到 Aspnet_isapi.dll 的文件類型執行訪問檢查。

文件授權不要求使用模擬。如果啓用了模擬,則應用程序執行的所有資源訪問均使用被模擬的調用者的標識。在這種情況下,請確保附加到資源上的 ACL 包含一個訪問控制項 (ACE),它可授予原調用者標識至少“讀”訪問權限。

標識已驗證身份的用戶

ASP.NET 將 WindowsPrincipal 對象與當前的 Web 請求關聯起來。這包含已驗證身份的 Windows 用戶的標識以及該用戶所屬的角色列表。在 Windows 身份驗證中,角色列表是由用戶所屬的 Windows 組集組成的。

以下代碼顯示如何獲取已驗證 Windows 用戶的標識,以及如何執行簡單的角色授權測試。

WindowsPrincipal user = User as WindowsPrincipal;
if (null != user)
{
  string username = user.Identity.Name;
  // Perform a role check
  if ( user.IsInRole(@"DomainName/Manager") )
  {
    // User is authorized to perform manager functionality
  }
}
else
{
  // Throw security exception as we don't have a WindowsPrincipal
}  

窗體身份驗證

當使用窗體身份驗證時,如果未驗證身份的用戶試圖訪問受保護的文件或資源(其中,URL 授權拒絕用戶訪問),該用戶所觸發的事件順序如 5 所示。

f08sn05

5. 窗體身份驗證的事件順序

以下描述 5 所示的事件順序:

1.

用戶發出一個針對 Default.aspx 的 Web 請求。

由於啓用了匿名訪問,所以 IIS 允許此類請求。ASP.NET 檢查 <authorization> 元素並查找 <denyusers=?" > 元素。

2.

將用戶重定向到由 <forms> 元素的 loginUrl 屬性指定的登錄頁 (Login.aspx)。

3.

用戶提供憑證並提交登錄窗體。

4.

根據數據存儲(SQL Server 或 Active Directory)檢驗憑證,並檢索角色(可選)。如果要使用基於角色的授權,則必須檢索角色列表。

5.

使用 FormsAuthenticationTicket 創建一個 Cookie 並將其發回客戶端。將角色存儲到票證中。通過在票證中存儲角色列表,可以避免爲相同用戶的每個後續 Web 請求訪問數據庫重新檢索列表。

6.

客戶端重定向將用戶重定向到原請求頁 (Default.aspx)。

7.

Application_AuthenticateRequest 事件處理程序(位於 Global.asax)中,使用票證創建 IPrincipal 對象並將其存儲在 HttpContext.User 中。

ASP.NET 檢查 <authorization> 元素並查找 <denyusers=?" > 元素。但此時對用戶進行身份驗證。

ASP.NET 檢查 <authorization> 元素以確保用戶在 <allow> 元素中。

授予用戶訪問 Default.aspx 的權限。

窗體身份驗證的開發步驟

以下列表重點介紹實現窗體身份驗證時必須執行的主要步驟:

1.

將 IIS 配置爲使用匿名訪問。

2.

將 ASP.NET 配置爲使用窗體身份驗證。

3.

創建登錄 Web 窗體並檢驗所提供的憑證。

4.

從自定義數據存儲中檢索角色列表。

5.

創建窗體身份驗證票證(在票證中存儲角色)。

6.

創建一個 IPrincipal 對象。

7.

IPrincipal 對象放到當前 HTTP 上下文中。

8.

基於用戶名/角色成員身份對用戶授權。

將 IIS 配置爲使用匿名訪問

必須在 IIS 中將應用程序的虛擬目錄配置爲使用匿名訪問。

將 IIS 配置爲使用匿名訪問的操作步驟

1.

啓動 Internet 信息服務管理工具。

2.

選擇應用程序的虛擬目錄,右擊,然後單擊“屬性”。

3.

單擊“安全目錄”。

4.

在“匿名訪問”和“身份驗證控制”組中,單擊“編輯”。

5.

選擇“匿名訪問”。

將 ASP.NET 配置爲使用窗體身份驗證

下面顯示一個配置示例。

<authentication mode="Forms">
  <forms name="MyAppFormsAuth" 
       loginUrl="login.aspx" 
       protection="Encryption"
       timeout="20" 
       path="/" >
  </forms>
</authentication>

創建登錄 Web 窗體並驗證提供的憑證

根據 SQL Server 數據庫或 Active Directory 檢驗憑證。

更多信息

請參見“How To Use Forms Authentication with SQL Server 2000”。

請參見“How To Use Forms Authentication with Active Directory”。

從自定義數據存儲中檢索角色列表

從 SQL Server 數據庫表中獲取角色,或從在 Active Directory 內配置的組/分發列表中獲取角色。詳細信息請參考前面的資源。

創建窗體身份驗證票證

在票證中存儲檢索到的角色。以下代碼演示了此過程。

// This event handler executes when the user clicks the Logon button
// having supplied a set of credentials
private void Logon_Click(object sender, System.EventArgs e)
{
  // Validate credentials against either a SQL Server database
  // or Active Directory
  bool isAuthenticated = IsAuthenticated( txtUserName.Text, 
                                          txtPassword.Text );
  if (isAuthenticated == true )
  {
    // Retrieve the set of roles for this user from the SQL Server
    // database or Active Directory. The roles are returned as a
    // string that contains pipe separated role names
    // for example "Manager|Employee|Sales|"
    // This makes it easy to store them in the authentication ticket

    string roles = RetrieveRoles( txtUserName.Text, txtPassword.Text );

    // Create the authentication ticket and store the roles in the
    // custom UserData property of the authentication ticket
    FormsAuthenticationTicket authTicket = new 
       FormsAuthenticationTicket(
                    1,                          // version
                    txtUserName.Text,           // user name
                    DateTime.Now,               // creation
                    DateTime.Now.AddMinutes(20),// Expiration
                    false,                      // Persistent
                    roles );                    // User data
     // Encrypt the ticket.
     string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
     // Create a cookie and add the encrypted ticket to the 
     // cookie as data.
     HttpCookie authCookie = 
               new HttpCookie(FormsAuthentication.FormsCookieName,
                              encryptedTicket);

     // Add the cookie to the outgoing cookies collection. 
     Response.Cookies.Add(authCookie); 
     // Redirect the user to the originally requested page
     Response.Redirect( FormsAuthentication.GetRedirectUrl(
                        txtUserName.Text, 
                        false ));
  }
}

創建一個 IPrincipal 對象

在位於 Global.asax 的 Application_AuthenticationRequest 事件處理程序中創建 IPrincipal 對象。除非您需要基於角色的擴展功能,否則,請使用 GenericPrincipal 類。在本範例中創建一個實現 IPrincipal 的自定義類。

將 IPrincipal 對象放到當前的 HTTP 上下文中

GenericPrincipal 對象的創建過程如下所示。

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
  // Extract the forms authentication cookie
  string cookieName = FormsAuthentication.FormsCookieName;
  HttpCookie authCookie = Context.Request.Cookies[cookieName];
  if(null == authCookie)
  {
    // There is no authentication cookie.
    return;
  } 
  FormsAuthenticationTicket authTicket = null;
  try
  {
    authTicket = FormsAuthentication.Decrypt(authCookie.Value);
  }
  catch(Exception ex)
  {
    // Log exception details (omitted for simplicity)
    return;
  }
  if (null == authTicket)
  {
    // Cookie failed to decrypt.
    return; 
  }
  // When the ticket was created, the UserData property was assigned a
  // pipe delimited string of role names.
  string[] roles = authTicket.UserData.Split(new char[]{'|'});

  // Create an Identity object
  FormsIdentity id = new FormsIdentity( authTicket ); 
  // This principal will flow throughout the request.
  GenericPrincipal principal = new GenericPrincipal(id, roles);
  // Attach the new principal object to the current HttpContext object
  Context.User = principal;
}
  

基於用戶名或角色成員身份對用戶進行授權

使用聲明性主體權限要求來限制對方法的訪問。使用命令性主體權限要求和/或明確的角色檢查 (IPrincipal.IsInRole) 在方法中執行細分的授權。

窗體實現原則

當使用 HTML 窗體捕獲憑證時,請使用 SSL。

無論何時通過網絡發送憑證或身份驗證 Cookie,除了對登錄頁使用 SSL 外,還應該對其他頁使用 SSL。這樣,可以減輕與 Cookie 重播相關的威脅。

根據自定義數據存儲驗證用戶的身份。請使用 SQL Server 或 Active Directory。

從自定義數據存儲中檢索角色列表,並在 FormsAuthenticationTicket 類的 UserData 屬性中存儲分隔的角色列表。這樣不必爲每個 Web 請求重複訪問數據存儲,從而提高了性能;而且還免去在身份驗證 Cookie 中存儲用戶憑證的麻煩。

如果角色列表很大並且有超過 Cookie 大小限制的危險,請在 ASP.NET 緩存對象或數據庫中存儲角色的詳細信息,並在每個後續請求中檢索這些信息。

對於初始身份驗證後的每個請求:

從位於 Application_AuthenticateRequest 事件處理程序的票證中檢索角色。

創建一個 IPrincipal 對象並將其存儲在 HTTP 上下文 (HttpContext.User) 中。.NET 框架還將其與當前 .NET 線程 (Thread.CurrentPrincipal) 關聯起來。

除非您有特殊的原因需要創建自定義的 IPrincipal 實現,否則請使用 GenericPrincipal 類。

使用兩種 Cookie:一種用於個性化,另一種用於安全的身份驗證和授權。將個性化 Cookie 作爲永久性的 Cookie(確保它不包含允許請求執行受限操作的信息;例如在站點的安全部分放置訂單)。

對於每個 Web 應用程序,請使用單獨的 Cookie 名稱(使用 <forms> 元素的 Forms 屬性)和路徑。如果針對某個應用程序驗證用戶的身份,這可確保在使用同一 Web 服務器承載的第二個應用程序時,不會將這些用戶作爲已驗證的用戶處理。

確保在客戶端瀏覽器中啓用 Cookie。對於不需要 Cookie 的窗體身份驗證方法,請參見本章後面的“無 Cookie 窗體身份驗證”。

更多信息

請參見“How To Use Forms Authentication with SQL Server 2000”。

請參見“How To Use Forms Authentication with Active Directory”。

請參見“How To Create GenericPrincipal Objects with Forms Authentication”。

承載多個使用窗體身份驗證的應用程序

如果在同一臺 Web 服務器上承載多個使用窗體身份驗證的 Web 應用程序,則在某個應用程序中已驗證身份的用戶可以請求另一個應用程序,而無需重定向到該應用程序的登錄頁。第二個應用程序中的 URL 授權規則可能會拒絕該用戶的訪問,而不會提供使用登錄窗體提供登錄憑證的機會。

這種情況只在以下情況下會發生:多個應用程序的 <forms> 元素的名稱和路徑屬性相同,而且每個應用程序在 Web.config 中使用相同的 <machineKey> 元素。

更多信息

有關此問題的詳細信息以及解決方法,請參見以下知識庫文章:

Q313116“PRB:Forms Authentication Requests Are Not Directed to loginUrl Page

Q310415“PRB:Mobile Forms Authentication and Different Web Applications

無 Cookie 窗體身份驗證

如果您需要無 Cookie 窗體身份驗證解決方案,請考慮使用 Microsoft Mobile Internet Toolkit 所使用的方法。移動窗體身份驗證建立在窗體身份驗證之上,但使用查詢字符串來傳遞身份驗證票證,而不是使用 Cookie。

更多信息

有關移動窗體身份驗證的詳細信息,請參見 Microsoft 知識庫文章 Q311568“INFO:How To Use Mobile Forms Authentication with Microsoft Mobile Internet Toolkit”。

Passport 身份驗證

如果應用程序使用 Passport 帳戶,而且您要在其他支持 Passport 的站點上實現單次登錄解決方案,則應使用 Passport 身份驗證。

當將 ASP.NET 配置爲使用 Passport 身份驗證時,就會提示用戶登錄並將該用戶重定向到 Passport 站點。成功檢驗憑證之後,用戶就會被重定向回您的站點。

將 ASP.NET 配置爲使用 Passport 身份驗證

要將 ASP.NET 配置爲使用 Passport 身份驗證,請使用以下 Web.config 設置。

<authentication mode="Passport">
  <passport redirectUrl="internal" />
</authentication>
<authorization>
  <deny users="?" />
  <allow users="*" />
</authorization>

將 Passport 標識映射到 Global.asax 中的角色

要將 Passport 標識映射到角色,請按如下所示在 Global.asax 中實現 PassportAuthentication_OnAuthentication 事件處理程序。

void PassportAuthentication_OnAuthenticate(Object sender, 
                                           PassportAuthenticationEventArgs e)
{
  if(e.Identity.Name == "0000000000000001")
  {
    string[] roles = new String[]{"Developer", "Admin", "Tester"};
    Context.User = new GenericPrincipal(e.Identity, roles);
  }
}
  

測試角色成員身份

以下代碼片段顯示瞭如何在 aspx 頁中檢索已驗證身份的 Passport 標識和檢查角色成員身份。

PassportIdentity passportId = Context.User.Identity as PassportIdentity;
if (null == passportId)
{
  Response.Write("Not a PassportIdentity");
  return;
}
Response.Write("IsInRole: Develeoper? " + Context.User.IsInRole("Developer"));
  

自定義身份驗證

如果 .NET 框架提供的身份驗證模塊均不能滿足您的確切身份驗證需要,則可以使用自定義身份驗證並實現您自己的身份驗證機制。例如,您的公司可能已經制訂了一個可由其他應用程序廣泛使用的自定義身份驗證策略。

要在 ASP.NET 中實現自定義身份驗證,請執行下列操作:

按如下所示在 Web.config 中配置身份驗證模式。這將通知 ASP.NET 不要調用它的任何內置的身份驗證模塊。

<authentication mode="None" />

創建實現 System.Web.IHttpModule 接口的類以創建自定義的 HTTP 模塊。此模擬應該掛鉤到 HttpApplication.AuthenticateRequest 事件中,並在要求身份驗證時對每個應用程序請求提供要調用的委派。

身份驗證模塊必須:

從調用者獲得憑證。

根據存儲檢驗憑證。

創建一個 IPrincipal 對象並將其存儲在 HttpContext.User 中。

創建並保護已驗證身份的令牌,並將其發回給用戶(通常在查詢字符串、Cookie 或隱藏的窗體字段中)。

在後續請求中獲得身份驗證令牌,對它進行檢驗,然後重新分發。

更多信息

有關如何實現自定義 HTTP 模塊的詳細信息,請參見 Microsoft 知識庫文章 Q307996“HOW TO:Create an ASP.NET HTTP Module Using Visual C# .NET”。

ASP.NET 的進程標識

使用權限最少的帳戶運行 ASP.NET (具體來說就是 Aspnet_wp.exe 輔助進程)。

使用權限最少的帳戶

使用權限最少的帳戶可以減少與進程攻擊相關的威脅。如果某個頑固的攻擊者設法破壞了運行 Web 應用程序的 ASP.NET 進程,則這些應用程序可以輕易地繼承和使用授予該進程帳戶的特權和訪問權限。配置爲權限最少的帳戶可以限制可能的潛在危害。

避免作爲 SYSTEM 運行

不要使用高權限的 SYSTEM 帳戶運行 ASP.NET,也不要授予 ASP.NET 進程帳戶“充當操作系統的一部分”的權限。您可能很想使用其中的一種方法,通過代碼調用 LogonUser API 以獲取固定的標識(通常用於網絡資源訪問)。有關替代方法,請參見本章後面的“訪問網絡資源”。

不要以 SYSTEM 的身份運行或不授予“充當操作系統的一部分”權限的原因包括:

當系統遭到攻擊時,它會大大增加攻擊者所造成的危害,但不能增加防範攻擊的能力。

它破壞了最少權限原則。ASPNET 已被明確配置爲運行 ASP.NET Web 應用程序使用的權限最少的帳戶。

更多信息

有關“充當操作系統的一部分”權限的詳細信息,請參見 1999 年 8 月 Microsoft Systems Journal Security Briefs 專欄文章。

域控制器和 ASP.NET 進程帳戶

一般情況下,不建議在域控制器上運行 Web 服務器,因爲對服務器的攻擊就是對域的攻擊。正如 Microsoft 知識庫文章 Q315158“BUG:ASP.NET Does Not Work with the Default ASPNET Account on a Domain Controller”中所概述的,如果需要在域控制器上運行 ASP.NET,則需要授予 ASP.NET 進程帳戶相應的權限。

使用默認的 ASPNET 帳戶

已將本地 ASPNET 帳戶明確配置爲使用盡可能最少的權限集運行 ASP.NET Web 應用程序。如果可能,儘量使用 ASPNET。

和 Machine.config 中的 <processModel> 元素所配置的一樣,默認情況下,ASP.NET Web 應用程序使用此帳戶運行。

<processModel userName="machine" password="AutoGenerate" />

machine 用戶名錶示 ASPNET 帳戶。當安裝 .NET 框架時,使用加密型密碼創建該帳戶。除了在安全帳戶管理器 (SAM) 數據庫中進行配置外,密碼還存儲在本地計算機上的本地系統授權 (LSA) 中。當系統啓動 ASP.NET 輔助進程時,系統就會從 LSA 中檢索密碼。

如果應用程序訪問網絡資源,則 ASPNET 帳戶必須能夠由遠程計算機驗證身份。您有兩種選擇:

將 ASPNET 帳戶的密碼重置爲某個已知值,然後在遠程計算機上創建一個重複帳戶(具有相同的名稱和密碼)。在以下情況下,此方法是惟一的選擇:

Web 服務器和遠程計算機位於單獨的域中,並且域間沒有信任關係。

Web 服務器和遠程計算機由防火牆隔開,並且您不想打開支持 Windows 身份驗證所需的端口。

如果您主要關心管理簡便性問題,請使用權限最少的域帳戶。

要避免必須手動更新和同步密碼,可以使用權限最少的域帳戶運行 ASP.NET。一定要完全鎖定域帳戶以減輕進程攻擊的威脅。如果某個攻擊者設法攻擊了 ASP.NET 輔助進程,則他或她可以訪問域資源,除非該帳戶已完全鎖定。

如果您使用本地帳戶而且該帳戶已被攻擊,則惟一遭受攻擊的計算機是您在上面創建重複帳戶的計算機。如果您使用域帳戶,則該帳戶對域中的每臺計算機都是可見的。但是,該帳戶仍然需要擁有訪問這些計算機的權限。

元素

Machine.config 文件中的 <processModel> 元素包含 userNamepassword 屬性,這些屬性指定應該使用哪些帳戶來運行 ASP.NET 輔助進程 (Aspnet_wp.exe)。

與傳統 ASP 應用程序的運行方式相比,ASP.NET 代碼從不在 dllhost.exe 進程中運行或作爲 IWAM_MACHINENAME 帳戶運行,即使在 IIS 中將應用程序保護級別設置爲“高(獨立)”。

發送到 IIS 的 ASP.NET 請求被直接路由到 ASP.NET 輔助進程 (Aspnet_wp.exe)。ASP.NET ISAPI 擴展 Aspnet_isapi.dll 在 IIS (Inetinfo.exe) 進程地址空間中運行。(這是由 InProcessIsapiApps 元數據庫項控制的;不要修改該元數據庫項)。ISAPI 擴展負責將請求路由到 ASP.NET 輔助進程。然後,ASP.NET 應用程序在 ASP.NET 輔助進程中運行,其中應用程序域提供隔離邊界。

在 IIS 6 中,您可以通過配置應用程序池來隔離 ASP.NET 應用程序,其中每個池都有自己的應用程序實例。

您可以使用多種方法來配置 <processModel> userName 屬性。例如:

"machine"。輔助進程作爲最少權限的默認 ASPNET 帳戶運行。此帳戶擁有網絡訪問權限,但不 能在網絡上的任何計算機上驗證該帳戶的身份,因爲該帳戶是計算機的本地帳戶,並且沒有頒發機構擔保此帳戶。在網絡上,此帳戶表示爲“MachineName/ASPNET”。

"system"。輔助進程作爲本地 SYSTEM 帳戶運行。此帳戶在本地計算機上具有廣泛的權限,而且還能夠使用計算機的憑證訪問網絡。在網絡上,此帳戶表示爲“DomainName/MachineName$”。

“特定驗證信息”。當您爲 userNamepassword 提供憑證時,請記住最少權限原則。如果您指定本地帳戶,則在網絡上不能對 Web 應用程序進行身份驗證,除非您在遠程計算機上創建重複帳戶。如果您選擇使用權限最少的域帳戶,請確保它僅有權訪問網絡上所需的計算機。

存儲加密的憑證

如果您使用自定義憑證,請使用 aspnet_setreg.exe 工具在註冊表中存儲加密的憑證。避免在 machine.config 中存儲明文憑證。

有關這個工具的詳細信息及下載,請參見 Microsoft 知識庫文章 Q329290“HOWTO:Use the ASP.NET Utility to Encrypt Credentials and Session State Connection Strings”。

以下示例顯示了這個工具使用前和使用後 userNamepassword 屬性的格式。請注意該屬性值如何指向安全的註冊表項和包含加密憑證的命名值。

<!-- Before -->
<processModel userName="SomeCustomAccount"
              password="ClearTextPassword" . . ./>

<!-- After -->
<processModel
        userName="registry:HKLM/SOFTWARE/YourSecureApp/processModel/
                  ASPNET_SETREG,userName"
        password="registry:HKLM/SOFTWARE/YourSecureApp/processModel/
                  ASPNET_SETREG,password" . . ./>

更多信息

有關從 ASP.NET Web 應用程序訪問網絡資源的詳細信息,請參見本章後面的“訪問網絡資源”。

有關如何創建用於運行 ASP.NET 的自定義帳戶的詳細信息,請參見“How To Create a Custom Account to Run ASP.NET”。

模擬

隨時 FileAuthorizationModule 的引入以及網關守衛和信任邊界的有效使用,現在看來,模擬技術在 ASP.NET 中是弊大於利。

模擬和本地資源

如果使用模擬並且從 Web 應用程序代碼訪問本地資源,則必須配置附加到每個受保護資源的 ACL,以包含一個至少授予已驗證用戶“讀”訪問權限的 ACE。

更好的方法是避免使用模擬,將權限授予 ASP.NET 進程帳戶,並使用 URL 授權、文件授權以及基於角色的聲明性和命令性檢查組合。

模擬和遠程資源

如果您使用模擬,然後從 Web 應用程序代碼訪問遠程資源,則除非使用基本身份驗證、窗體身份驗證或 Kerberos 身份驗證,否則訪問將會失敗。如果您使用 Kerberos 身份驗證,則必須將用戶帳戶相應地配置爲使用委派。在 Active Directory 中,必須將它們標記爲“敏感帳戶,不能被委派”。

更多信息

有關如何配置 Kerberos 委派的詳細信息,請參見:

Intranet Security”一章中的“將原調用者傳遞到數據庫”。

How To Implement Kerberos Delegation for Windows 2000”。

模擬和線程

如果某個正在模擬的線程創建了一個新線程,則該新線程將繼承 ASP.NET 進程帳戶的安全性上下文,而不是繼承被模擬帳戶的安全性上下文。

訪問系統資源

默認情況下,ASP.NET 不執行模擬。因此,如果 Web 應用程序訪問本地系統資源,則它使用與 Aspnet_wp.exe 輔助進程相關聯的安全性上下文完成此任務。安全性上下文是由運行輔助進程使用的帳戶決定的。

訪問事件日誌

權限最少的帳戶擁有足夠的權限,能夠使用現有事件源將記錄寫入事件日誌中。但是,它們沒有足夠的權限來創建新的事件源,這要求在下面的註冊表配置單元底下設置一個新項。

HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Eventlog/<log>

爲了避免出現這種問題,請在安裝時創建由應用程序使用的事件源(如果可以使用管理員權限的話)。一個好的辦法是使用可由 Windows Installer(如果使用 .msi 部署的話)或 InstallUtil.exe 系統實用程序(如果沒有使用 .msi 部署)實例化的 .NET 安裝程序類。

如果在安裝時無法創建事件源,則必須將權限添加到以下注冊表項中,並授予某個被模擬帳戶的 ASP.NET 進程帳戶訪問權限(如果應用程序使用模擬的話)。

HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Eventlog 

帳戶必須擁有以下最少權限:

查詢項值

設置項值

創建子項

枚舉子項

通知

在將權限應用於註冊表後,可以使用以下代碼從 ASP.NET 寫入應用程序事件日誌:

string source = "Your Application Source";
string logToWriteTo = "Application";
string eventText = "Sample Event";

if (!EventLog.SourceExists(source))
{
  EventLog.CreateEventSource(source, logToWriteTo);
}
EventLog.WriteEntry(source, eventText, EventLogEntryType.Warning, 234);
  

訪問註冊表

應用程序訪問的任何註冊表項要求在 ACL 中使用 ACE,以便至少授予 ASP.NET 進程帳戶“讀”訪問權限。

更多信息

有關安裝程序類和InstallUtil.exe 實用工具的詳細信息,請參見 MSDN 上的 .NET 框架 SDK 的“.NET 框架工具”部分。

訪問 COM 對象

在傳統 ASP 中,使用單線程單元 (STA) 線程池中的線程來處理請求。在 ASP.NET 中,使用多線程單元 (MTA) 線程池中的線程來處理請求。這會給調用單元模型對象的 ASP.NET Web 應用程序造成不利影響。

單元模型對象

當 ASP.NET Web 應用程序調用單元模型對象(如 Visual Basic 6 COM 對象)時,需要注意以下兩個問題:

您必須用 AspCompat 指令標記 ASP.NET 頁面(如下所示)。

<%@ Page Language="C#" AspCompat="True" %>

不要在特定的 Page 事件處理程序以外創建 COM 對象。始終在 Page 事件處理程序(例如, Page_LoadPage_Init)中創建 COM 對象。不要在頁面的構造函數中創建 COM 對象。

需要 AspCompat 指令

默認情況下,ASP.NET 使用 MTA 線程處理請求。在從 ASP.NET 調用單元模型對象時,將會導致線程切換,這是因爲 MTA 線程不能直接訪問單元模型對象(COM 將使用 STA 線程)。

如果指定 AspCompat,則會由 STA 線程處理頁面。這可以避免從 MTA 到 STA 的線程切換。如果 Web 應用程序使用模擬功能,從安全角度講這是非常重要的,因爲線程切換將會導致丟失模擬令牌。新線程將沒有關聯的模擬令牌。

ASP.NET Web 服務不支持 AspCompat 指令。這意味着,在從 Web 服務代碼調用單元模型對象時,將會發生線程切換並且丟失線程模擬令牌。這通常導致出現“拒絕訪問”異常錯誤。

更多信息

有關詳細令牌,請參見以下知識庫文章:

文章 Q303375“INFO:XML Web Services and Apartment Objects

文章 Q325791“PRB:Access Denied Error Message Occurs When You Impersonate an Account in ASP.NET and Then Call STA COM Components

有關如何確定當前執行代碼的標識的詳細信息,請參見“Troubleshooting”一章中的“確定標識”部分。

不要在特定 Page 事件以外創建 COM 對象

不要在特定 Page 事件處理程序以外創建 COM 對象。以下代碼片段闡釋了不要執行哪些操作。

<%@ Page Language="C#" AspCompat="True" %>
<script runat="server">
  // COM object created outside of Page events
  YourComObject obj = new apartmentObject();
  public void Page_Load()
  {
    obj.Foo()
  }
</script>

在使用單元模型對象時,一定要在特定 Page 事件(例如 Page_Load)中創建對象(如下所示)。

<%@ Page Language="C#" AspCompat="True" %>
<script runat="server">
public void Page_Load()
{
  YourComObject obj  = new apartmentObject();
  obj.Foo()
}
</script>

更多信息

有關詳細信息,請參見 Microsoft 知識庫文章 Q308095“PRB:Creating STA Components in the Constructor in ASP.NET ASPCOMPAT Mode Negatively Impacts Performance”。

COM+ 中的 C# 和 VB .NET 對象

Microsoft C#_ 開發工具和 Microsoft Visual Basic_ .NET 開發系統支持所有的線程模擬(自由線程、中性、兩者和單元)。默認情況下,將 COM+ 中駐留的 C# 和 Visual Basic .NET 對象標記爲“兩者”。因此,當 ASP.NET 調用它們時,可以直接進行訪問,而不會發生線程切換。

訪問網絡資源

應用程序可能需要訪問網絡資源。一定要能夠標識以下內容:

應用程序需要訪問的資源。

例如,文件共享上的文件、數據庫、DCOM 服務器和 Active Directory 對象等等。

用來執行資源訪問的標識。

如果應用程序訪問遠程資源,則遠程計算機必須能夠對此標識進行驗證。

有關訪問遠程 SQL Server 數據庫的信息,請參見“數據訪問安全性”一章。

可以使用以下任一種方法,從 ASP.NET 應用程序中訪問遠程資源:

使用 ASP.NET 進程標識。

使用服務組件。

使用匿名 Internet 用戶帳戶(例如,IUSR_MACHINE)。

使用 LogonUser API 和模擬特定的 Windows 標識。

使用原調用者。

使用 ASP.NET 進程標識

如果沒有將應用程序配置爲使用模擬,在應用程序試圖訪問遠程資源時,ASP.NET 進程標識就會提供默認標識。如果使用 ASP.NET 進程帳戶訪問遠程資源,您有三種選擇:

使用鏡像帳戶。

這是最簡單的方法。您在遠程計算機上使用匹配的用戶名和密碼創建一個本地帳戶。您必須在用戶管理器中將 ASPNET 帳戶密碼更改爲已知值(始終使用強密碼)。然後,必須在 Machine.config 中的“AutoGenerate”元素上明確地設置它,並替換現有的“AutoGenerate”值。避免使用明文憑證。如前面所述,使用 aspnet_setreg.exe 實用工具在註冊表中存儲加密憑證。

重要 如果將 ASPNET 密碼更改爲一個已知值,則 LSA 中的密碼不再與 SAM 帳戶密碼匹配。如果需要恢復爲“AutoGenerate”默認值,則需要執行以下任一操作:

運行 Aspnet_regiis.exe,將 ASP.NET 重置爲其默認配置。有關詳細信息,請參見 Microsoft 知識庫文章 Q306005“HOWTO:Repair IIS Mapping After You Remove and Reinstall IIS”。

創建一個權限最少的自定義本地帳戶以運行 ASP.NET,並在遠程計算機上創建一個重複帳戶。

使用一個權限最少的域帳戶運行 ASP.NET。

假設客戶端計算機和服務器計算機都位於同一個域或信任域內。

更多信息

有關配置 ASP.NET 進程帳戶的詳細信息,請參見“How To Create a Custom Account to Run ASP.NET”。

使用服務組件

可以使用配置爲以固定標識運行的進程外服務組件來訪問網絡資源。圖 6 顯示了這種方式。

f08sn06

6. 使用進程外服務組件爲網絡資源訪問提供固定標識

使用進程外服務組件(在 Enterprise Services 服務器應用程序中)具有以下優點:

在標識使用上具有很大靈活性。不是僅依賴於 ASP.NET 標識。

受信任的或具有更高權限的代碼可以與主 Web 應用程序分開。

從安全角度來講,由於增加了一個進程,所以提高了安全門檻。對於攻擊者而言,穿過進程邊界到達具有更高權限的進程要困難得多。

如果您需要使用 LogonUser API 調用進行手動模擬,則可以在與主 Web 應用程序分開的進程中執行此操作。

要調用 LogonUser,您必須授予 Enterprise Services 進程帳戶“充當操作系統的一部分”的權限。可以通過提高與 Web 應用程序分開的進程的權限來減少安全隱患。

使用匿名 Internet 用戶帳戶

如果將 IIS 配置爲使用匿名身份驗證,則可以使用匿名 Internet 用戶帳戶訪問網絡資源。如果以下任一種情況屬實,就會發生這種情況:

應用程序支持匿名訪問。

應用程序使用窗體、Passport 或自定義身份驗證(其中將 IIS 配置爲使用匿名訪問)。

使用匿名帳戶訪問遠程資源

1.

將 IIS 配置爲使用匿名身份驗證。可以根據應用程序的身份驗證要求,將 ASP.NET 身份驗證模式設置爲“Windows”、“窗體”、“Passport”或“無”。

2.

將 ASP.NET 配置爲使用模擬。在 Web.config 中使用下列設置:

<identity impersonate="true" />

3.

將匿名帳戶配置爲權限最少的域帳戶,

- 或者 -

在遠程計算機上使用相同的用戶名和密碼複製匿名帳戶。在不信任域之間進行調用時,或者通過沒有打開支持集成 Windows 身份驗證所需端口的防火牆進行調用時,必須使用此方法。

要支持這種方法,您還必須:

1.

使用 Internet 服務管理器清除匿名帳戶的“允許 IIS 控制密碼”複選框。

如果選擇此選項,則使用指定匿名帳戶創建的登錄會話最終得到的是 NULL 網絡憑證(因此不能用來訪問網絡資源)。如果不選擇此選項,則登錄會話是一個具有網絡憑證的交互式登錄會話。

2.

在用戶管理器和 Internet 服務管理器中均設置帳戶的憑證。

重要如果您模擬匿名帳戶(例如,IUSR_MACHINE),則必須禁止該帳戶訪問資源(使用進行適當配置的 ACL)。對於應用程序需要訪問的資源,必須(至少)授予匿名帳戶“讀”訪問權限。應該拒絕匿名帳戶訪問所有其他資源。

承載多個 Web 應用程序

對於 Web 站點中的每一個虛擬根目錄,可以使用一個單獨的匿名 Internet 用戶帳戶。在承載環境中,這允許您分別授權、跟蹤和審覈來自不同 Web 應用程序的請求。 7 顯示了這種方式。

f08sn07

7. 爲每個應用程序模擬不同的匿名 Internet 用戶帳戶 (v-dir)

爲特定的虛擬目錄配置匿名 Internet 用戶帳戶

1.

“管理工具”程序組中啓動“網絡管理工具”。

2.

選擇要配置的虛擬目錄,右擊,然後單擊“屬性”。

3.

單擊“目錄安全性”選項卡。

4.

在“匿名訪問”和“身份控制”組中,單擊“編輯”。

5.

選擇“匿名訪問”,然後單擊“編輯”。

6.

鍵入在匿名用戶連接到站點時希望 IIS 使用的帳戶的用戶名和密碼。

7.

確保沒有選中“允許 IIS 控制密碼”。

使用 LogonUser 並模擬特定的 Windows 標識

可以使用以下方法模擬特定的標識:在 Web.config 中的 <identity> 元素上配置用戶名和密碼屬性,或者在應用程序代碼中調用 Win32_ LogonUser API。

重要 正如本章前面所提到的,當在 Windows 2000 服務器上使用 .NET Framework 1.0 時,不推薦使用 LogonUser 和固定的模擬標識,因爲它強制給 ASP.NET 進程帳戶授予“充當操作系統的一部分”權限。

Microsoft Windows .NET Server 2003 將取消這一限制。另外,在 Windows 2000 中,.NET Framework 1.1 版會爲此方案提供一個增強功能。登錄會由 IIS 進程執行,因此 ASP.NET 不需要“充當操作系統的一部分”權限。

使用原調用者

要使用原調用者的標識訪問遠程資源,您必須能夠將調用者的安全性上下文從 Web 服務器委派到遠程計算機。

可擴展性警告 如果使用原調用者的模擬標識訪問應用程序的數據服務層,則會嚴重影響應用程序的可擴展性,這是因爲數據庫連接池的效率非常低。對於每個用戶而言,數據庫連接的安全性上下文是不同的。

以下身份驗證方案支持委派:

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

映射到 Windows 帳戶的客戶端證書。映射必須由 IIS 執行。

基本。基本身份驗證支持遠程資源訪問,因爲在 Web 服務器上以明文形式提供原調用者的憑證的。可以使用這些憑證響應來自遠程計算機的身份驗證質詢。

必須將基本身份驗證與交互式或批處理登錄會話配合使用。可以在 IIS 元數據庫中配置從基本身份驗證產生的登錄會話類型。有關詳細信息,請參見 MSDN 上的 Platform SDK:Internet Information Services 5.1。

重要 在支持委派的方法中,基本身份驗證是最不安全的一種方法。這是因爲明文用戶名和密碼通過網絡從瀏覽器傳遞到服務器,並且它們緩存在 Web 服務器的內存中。可以使用 IIS 在傳遞過程中保護憑證,但只要可能就應該避免在 Web 服務器上緩存明文憑證。

使用原調用者訪問遠程資源

1.

將 IIS 配置爲使用集成 Windows (Kerberos)、證書(帶 IIS 證書映射)或基本身份驗證。

2.

將 ASP.NET 配置爲使用 Windows 身份驗證和模擬。

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

3.

如果使用 Kerberos 委派,請將 Active Directory 帳戶配置爲使用委派。

更多信息

有關配置 Kerberos 委派的詳細信息,請參見“How To Implement Kerberos Delegation for Windows 2000”。

有關 IIS 證書映射的詳細信息,請參見 http://www.microsoft.com/technet/treeview/default.asp?url=/technet/prodtechnol/ad/windows2000/howto/mapcerts.asp

有關 ASP.NET 模擬的詳細信息,請參見 MSDN 中的 .NET 框架開發人員指南

訪問 UNC 文件共享上的文件

如果應用程序需要使用 ASP.NET 訪問統一命名約定 (UNC) 共享上的文件,則一定要添加共享文件夾的 NTFS 權限。您還需要設置共享的權限,以便授予 ASP.NET 進程帳戶或模擬的標識至少“讀”訪問權限(如果將應用程序配置爲使用模擬的話)。

訪問非 Windows 網絡資源

如果應用程序需要訪問非 Windows 資源(例如位於非 Windows 平臺上的數據庫或大型機應用程序),則需要考慮以下問題:

與資源相關的網關守衛和信任邊界是什麼?

身份驗證需要哪些憑證?

資源是否需要知道原調用者的標識,或者它是否信任調用應用程序(使用固定標識或服務標識)?

與建立連接相關的性能開銷有多大?如果開銷很大,則可能需要實現連接池;例如,使用 Enterprise Services 的對象池功能。

如果資源需要能夠對原調用者進行身份驗證(並且不能選用 Windows 身份驗證),則可以選擇以下方法:

使用(方法調用)參數傳遞憑證。

在連接字符串中傳遞憑證。使用 SSL 或 IPSec 保護通過網絡傳遞的明文憑證。

在應用程序中安全地存儲憑證,例如使用 DPAPI。有關安全地存儲數據庫連接字符串的詳細信息,請參見“數據訪問安全性”一章中的“安全存儲數據庫連接字符串”。

使用兩個平臺都能訪問的集中數據存儲進行身份驗證;例如,LDAP 目錄。

安全通信

使用 SSL 保護瀏覽器和 Web 服務器之間通信鏈路的安全。SSL 提供消息機密性和消息完整性。使用 SSL 和/或 IPSec 提供從 Web 服務器到應用程序服務器或數據庫服務器的安全通道。

更多信息

有關安全通信的詳細信息,請參見“Secure Communication”一章。

存儲機密

Web 應用程序通常需要存儲機密。需要妥善保管這些機密,以防止不道德的管理員和有惡意的 Web 用戶進行訪問,例如:

不道德的管理員。不應該授予不道德的管理員和其他用戶查看特權信息的權限。例如,不應該授予 Web 服務器管理員讀取網絡中 SQL Server 計算機上的 SQL Server 登錄帳戶密碼的權限。

惡意的 Web 用戶。即使可以使用某些組件(例如 FileAuthorizationModule)禁止用戶訪問特權文件(如果攻擊者確實獲得訪問配置文件的權限),文件中的機密也不應該以純文本形式存儲。

機密的典型示例包括:

SQL 連接字符串。一個常見的錯誤是以純文本形式存儲用戶名和密碼。建立使用 Windows 身份驗證而不是 SQL 身份驗證。如果不能使用 Windows 身份驗證,請參見“數據訪問安全性”一章中的以下部分,它們介紹了其他的安全方案:

“安全地存儲數據庫連接”

“安全通信”

SQL 應用程序角色使用的憑證。必須使用需要角色名及相關密碼的存儲過程激活 SQL 應用程序角色。有關詳細信息,請參見“數據訪問安全性”一章中的“授權”。

Web.config 中的固定標識。例如:

<identity impersonate="true" userName="bob" password="inClearText"/>

aspnet_setreg.exe 實用工具允許您將明文憑證替換爲指向包含加密憑證的安全註冊表項的指針。

Machine.config 中的進程標識。例如:

<process userName="cUsTuMUzerName" password="kUsTumPazzWerD" >

按照 <identity> 元素,您必須使用 aspnet_setreg.exe 將加密憑證存儲在註冊表中。

用於安全地存儲數據的密鑰。無法在軟件中安全地存儲密鑰。但是,可以使用某些任務降低風險。例如,創建一個自定義的配置節處理程序,它使用不對稱加密對會話密鑰進行加密。然後,可以將會話密鑰存儲在配置文件中。

SQL Server 會話狀態。要使用 SQL 服務器管理 ASP.NET Web 應用程序會話狀態,請使用以下 Web.config 設置。

<sessionState … stateConnectionString="tcpip=127.0.0.1:42424"
                sqlConnectionString="data source=127.0.0.1;
                user id=UserName;password=MyPassword" />

aspnet_setreg.exe 也支持 <sessionState> 元素中的 stateConnectionStringsqlConnectionString 屬性,該元素允許您將這些值以加密格式存儲到註冊表中。

用於根據數據庫進行窗體身份驗證的密碼

如果應用程序根據數據庫檢驗身份驗證憑證,請不要將密碼存儲在數據庫中。使用帶有 Salt 值的密碼哈希值並對哈希值進行比較。

有關更多信息,請參見“數據訪問安全性”一章中的“對數據庫進行用戶身份驗證”。

在 ASP.NET 中存儲機密的選項

.NET Web 應用程序開發人員可以使用多種方法來存儲機密。它們是:

“.NET安全類”。.NET 框架包含可用於加密和解密的類。這些方法要求安全地存儲加密密鑰。

“數據保護API” (DPAPI)。DPAPI 是一對 Win32 API,它使用從用戶密碼派生的密鑰對數據進行加密和解密。在使用 DPAPI 時,您並不需要進行密鑰管理。操作系統將對作爲用戶密碼的密鑰進行管理。

“COM+構造字符串”。如果應用程序使用服務組件,則可以在對象構造字符串中存儲機密。該字符串以明文形式存儲在 COM+ 目錄中。

CAPICOM。這是一個 Microsoft COM 對象,它提供對基礎加密 API 基於 COM 的訪問。

Crypto API。這些 API 是執行加密和解密的低級 Win32 API。

更多信息

有關詳細信息,請參見 MSDN 上 Platform SDK 中的加密技術、CryptoAPI 和 CAPICOM 條目。

考慮將機密存儲在單獨邏輯捲上的文件中

考慮將 Web 應用程序目錄安裝到操作系統所在卷以外的邏輯捲上(例如 E: 而不是 C:)。這意味着 Machine.config(位於 C:/WINNT/Microsoft.NET 下)和其他可能包含機密的文件(例如通用數據鏈接 (UDL) 文件)都位於 Web 應用程序目錄以外的邏輯捲上。

此方法的基本原理是防止出現可能的文件規範化和目錄遍歷錯誤,因爲:

文件規範化錯誤可能會公開 Web 應用程序文件夾中的文件。

文件規範化例程返回文件路徑的規範形式。這通常是絕對路徑名,其中已完全解析所有相對引用和對當前目錄的引用。

目錄遍歷錯誤可能會公開同一邏輯捲上其他文件夾中的文件。

公開其他邏輯捲上文件的上述類型錯誤尚未發佈。

保護會話和視圖狀態

Web 應用程序必須管理各種類型的狀態,其中包括視圖狀態和會話狀態。本節討論 ASP.NET Web 應用程序的安全狀態管理。

保護視圖狀態

如果 ASP.NET Web 應用程序使用視圖狀態:

按如下所示將 enableViewStateMac 設置爲 true,以確保視圖狀態的完整性(確保在傳遞過程中沒有對它進行修改)。這樣,在從客戶端發回頁面時,ASP.NET 就會在該頁面的視圖狀態上生成消息身份驗證代碼 (MAC)。

<% @ Page enableViewStateMac=true >
  

配置 Machine.config 中 <machineKey> 元素的 validation 屬性,指定數據檢驗所使用的加密類型。請考慮 validation 屬性的以下幾方面的問題:

安全哈希算法 1 (SHA1) 生成的哈希大小比消息摘要 5 (MD5) 大,因而可以認爲它更安全。但是,在傳遞過程中或在客戶端可能會解碼使用 SHA1 或 MD5 保護的視圖狀態,並可能以純文本形式進行查看。

使用三重數據加密標準 (3DES) 檢測視圖狀態中的變化,並且還可以在傳遞過程中對視圖狀態進行加密。在處於這種狀態時,即使視圖狀態被解碼,也不能以純文本形式進行查看。

保護 Cookies

在傳遞過程中,應該使用 SSL 保護包含身份驗證或授權數據或其他機密數據的 Cookie。對於窗體身份驗證,可以使用 FormsAuthentication.Encrypt 方法加密以 Cookie 形式在客戶端和服務器之間傳遞的身份驗證票證。

保護 SQL 會話狀態

默認(進程內) ASP.NET 會話狀態處理程序會受到某些限制。例如,它不能在網絡場中的其他計算機上運行。爲了克服此限制,ASP.NET 允許在 SQL Server 數據庫中存儲會話狀態。

可以在 Machine.config 或 Web.config 中配置 SQL 會話狀態。machine.config 的默認設置如下所示。

<sessionState mode="InProc" 
              stateConnectionString="tcpip=127.0.0.1:42424" 
              stateNetworkTimeout="10"
              sqlConnectionString="data source=127.0.0.1;user id=sa;password="
              cookieless="false" timeout="20"/>

默認情況下, SQL 腳本 InstallSqlState.sql (用於生成 SQL 會話狀態使用的數據庫)安裝在以下位置:

C:/WINNT/Microsoft.NET/Framework/v1.0.3705

在使用 SQL 會話狀態時,需要考慮以下兩個問題。

必須保護數據庫連接字符串的安全。

在網絡上傳遞時,必須保護會話狀態的安全。

保護數據庫連接字符串

如果使用 SQL 身份驗證連接到服務器,則連接字符串在包含用戶名和密碼的 sqlConnectionString 屬性中指定。使用 aspnet_setreg.exe 實用工具在註冊表中存儲加密的連接字符串。以下示例顯示了使用 aspnet_setreg.exe 前後的 <sessionState> 元素。

<!-- Before -->
<sessionState 
    mode="SQLServer", 
    sqlConnectionString="data source=Server;user id=userID;password=pwd" . . . />
<!-- After -->
<sessionState mode="SQLServer"
              sqlConnectionString="registry:HKLM/SOFTWARE/YourSecureApp/
              sessionState/ASPNET_SETREG,sqlConnectionString" />

如果您使用 ASP.NET 狀態服務,也可以使用 aspnet_setreg.exe 來加密 stateConnectionString 屬性。

如果可能,應該對 SQL Server 狀態數據庫使用 Windows 身份驗證。這將帶來其他一些優點:連接字符串不包含憑證,憑證不通常網絡傳遞到數據庫服務器。

要使用 Windows 身份驗證,可以使用 ASP.NET 進程標識(通常是 ASPNET)

1.

在數據庫服務器上創建一個重複的帳戶(使用相同的名稱和密碼)。

2.

爲該帳戶創建 SQL 登錄。

3.

ASPState 數據庫中創建一個數據庫用戶,並將 SQL 登錄映射到該新用戶。

ASPState 數據庫是由 InstallSQLState.sql 腳本創建的。

4.

創建一個用戶定義的數據庫角色,並將數據庫用戶添加到該角色。

5.

在數據庫中爲該數據庫角色配置權限。

然後,可以更改連接字符串以使用受信任的連接(如下所示):

sqlConnectionString="server=127.0.0.1;
                     database=StateDatabase;
                     Integrated Security=SSPI;"

在網絡上保護會話狀態

在通過網絡將會話狀態傳遞到 SQL Server 數據庫時,可能需要對會話狀態進行保護。這取決於承載 Web 服務器和數據服務器的網絡的安全性。如果已在受信任環境中對數據庫進行物理保護,則可能不必採取這一額外的安全措施。

可以使用 IPSec 保護 Web 服務器和 SQL Server 之間的所有 IP 通信,或者使用 SSL 保護到 SQL Server 的鏈路。通過使用此方法,您可以選擇只加密用於會話狀態的連接,而不是在計算機之間進行的所有通信。

更多信息

有關如何設置 SQL 會話狀態的詳細信息,請參見 Microsoft 知識庫文章 Q317604“HOW TO:Configure SQL Server to Store ASP.NET Session State”。

有關對 SQL Server 使用 SSL 的詳細信息,請參見“How To Use SSL to Secure Communication with SQL Server 2000”。

有關使用 IPSec 的詳細信息,請參見“How To Use IPSec to Provide Secure Communication Between Two Servers”。

網絡場注意事項

在網絡場方案中,不能保證來自同一個客戶端的後續請求由同一個 Web 服務器提供服務。對於狀態管理和任何取決於 Machine.config 中 <machineKey> 元素所保存的屬性的加密而言,這會產生不利影響。

會話狀態

默認 ASP.NET 進程內會話狀態處理(它鏡像以前的 ASP 功能)產生服務器關係,並且不能在網絡場方案中使用。對於網絡場部署,必須在進程外將會話狀態存儲到 ASP.NET 狀態服務或 SQL Server 數據庫中(如前所述)。

不能依賴應用程序狀態來保存網絡場(將 Web 應用程序配置爲在多臺服務器上運行)或網絡園(將 Web 應用程序配置爲在多個處理器上運行)方案中的全局計數器或惟一值,因爲在進程或計算機之間不能共享應用程序狀態。

DPAPI

DPAPI 能夠與機器存儲或用戶存儲(需要一個已加載的用戶配置文件)配合使用。如果您將 DPAPI 和機器存儲一起使用,那麼加密字符串是給定計算機所特有的,因此您必須在每臺計算機上生成加密數據。不要在網絡場或羣集中的計算機之間複製加密數據。

如果將 DPAPI 和用戶存儲一起使用,則可以用一個漫遊的用戶配置文件在任何一臺計算機上解密數據。

更多信息

有關 DPAPI 的詳細信息,請參見“數據訪問安全性”一章。

在網絡場中使用窗體身份驗證

如果使用窗體身份驗證,則網絡場中的所有服務器必須共享一個通用機密密鑰,此密鑰用於身份驗證票證的加密、解密和驗證。

機密密鑰保存位於 Machine.config 的 <machineKey> 元素中。默認設置如下所示。

<machineKey validationKey="AutoGenerate" 
            decryptionKey="AutoGenerate" 
            validation="SHA1"/> 

此設置導致每臺機器生成一個不同的檢驗和解密密鑰。必須更改 <machineKey> 元素,並將通用密鑰值放在網絡場中的所有服務器上。

元素

可以使用 Machine.config 中的 <machineKey> 元素,配置用於加密和解密窗體身份驗證 Cookie 數據和視圖狀態的密鑰。

在調用 FormsAuthentication.EncryptFormsAuthentication.Decrypt 方法以及創建或檢索視圖狀態時,將參考 <machineKey> 元素中的值。

<machineKey validationKey="autogenerate|value"
            decryptionKey="autogenerate|value"
            validation="SHA1|MD5|3DES" />

validationKey 屬性

validationKey 屬性值用於創建和檢驗視圖狀態和窗體身份驗證票證的 MAC 代碼。此檢驗屬性表明在執行 MAC 生成時使用哪種算法。請注意以下方面:

在使用窗體身份驗證時,此密鑰與 <forms> protection 屬性配合使用。如果將保護屬性設置爲 Validation,然後調用 FormsAuthentication.Encrypt 方法,則使用票證值和 validationKey 來計算附加到 Cookie 中的 MAC。在調用 FormsAuthentication.Decrypt 方法時,就會計算 MAC 並將它與附加到票證上的 MAC 進行比較。

在使用視圖狀態時,可以使用控件的視圖狀態和 validationKey 來計算附加到視圖狀態上的 MAC。在將視圖狀態從客戶端發回時,應重新計算 MAC 並將它與附加到視圖狀態上的 MAC 進行比較。

decryptionKey 屬性

decryptionKey 屬性值用於加密和解密窗體身份驗證票證和視圖狀態。可以使用 DES 或 Triple DES (3DES) 算法。具體的算法取決於服務器上是否安裝了 Windows 2000 高度加密包。如果安裝了該程序包,則使用 3DES,否則使用 DES。請注意以下方面:

在使用窗體身份驗證時,密鑰與 <forms> protection 屬性配合使用。如果將 protection 屬性設置爲 Encryption,並且調用了 FormsAuthentication.EncryptDecrypt 方法,則使用指定的 decryptionKey 值加密或解密票證值。

通過使用視圖狀態,在將控件的視圖狀態值發送到客戶端時,使用 decryptionKey 值對它進行加密;並在客戶端將數據發回服務器時對它進行解密。

Validation 屬性

此屬性規定檢驗、加密和解密時使用哪種算法。它可以採用 SHA1、MD5 或 3DES 值。以下是這些值的描述:

SHA1。如果設置爲 SHA1,則實際使用 HMACSHA1 算法。它生成 160 位(20 個字節)的輸入哈希值或摘要。HMACSHA1 是一種加密哈希算法。此算法的輸入密鑰是由 validationKey 屬性指定的。

SHA1 由於比其他算法具有更大的摘要,因此成爲常用的算法。

MD5。它使用 MD5 算法生成 20 個字節的哈希值。

3DES。它使用 Triple DES (3DES) 算法加密數據。

在將驗證屬性設置爲 3DES 時,窗體身份驗證實際上並不使用它,而是使用 SHA1。

更多信息

有關如何創建適於放在 Machine.config 中的密鑰的信息,請參見 Microsoft 知識庫文章 Q312906“HOW TO:Create Keys by using Visual C# .NET for Use in Forms Authentication”。

有關 Windows 2000 高度加密包的詳細信息,請參見 http://www.microsoft.com/windows2000/downloads/recommended/encryption/

小結

本章介紹了各種保護 ASP.NET Web 應用程序的技術和方法。本章提供的大多數指南和建議同樣適用於開發 ASP.NET Web 服務和由 ASP.NET 駐留的 .NET Remoting 對象。概括如下:

如果應用程序使用窗體身份驗證,而且在用戶身份驗證中需要考慮性能問題,則檢索角色列表並將其存儲在身份驗證票證中。

如果使用窗體身份驗證,則始終給每個請求創建一個主體並將其存儲在上下文中。

如果角色太多而無法存儲在身份驗證 Cookie 中,則使用全局應用程序緩存來存儲角色。

不要創建權限最少的自定義帳戶來運行 ASP.NET。而是應該更改 ASPNET 帳戶密碼,並在應用程序需要訪問的任何遠程 Windows 服務上創建重複帳戶。

如果必須創建自定義帳戶以運行 ASP.NET,請使用權限最少的用戶。例如:

如果主要考慮管理問題,請使用權限最少的域帳戶。

如果使用本地帳戶,則必須在 Web 應用程序需要訪問的任何遠程計算機上創建重複帳戶;如果應用程序需要訪問非信任域中的資源或者防火牆禁止 Windows 身份驗證,則必須使用本地帳戶。

不要使用本地 SYSTEM 帳戶來運行 ASP.NET。

不要授予 ASPNET 帳戶“充當操作系統的一部分”權限。

在以下情況中使用 SSL:

在瀏覽器和 Web 服務器之間傳送安全敏感信息時。

使用基本身份驗證(以保護憑證)時。

使用窗體身份驗證進行身份驗證(與個性化相對)時。

避免以純文本形式存儲機密。

不要在 machine.config 和 Web.config 中存儲純文本憑證。對於 <identity>, <processModel> 和 <sessionState> 元素,使用 aspnet_setreg.exe 實用工具在註冊表中存儲加密憑證。

轉到原英文頁面


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