一.概念
在網站中一般都要涉及到使用者身份的驗證和管理,網站中的使用者管理主要分為四個主要部分,分別是使用者身份的驗證,使用者存取權限的驗證,使用者的管理,使用者的角色管理。
以往在寫使用者驗證和管理功能的時候,一般都是由開發人員自己通過SESSION或COOKIE取得使用者的身份標識,併到資料庫中進行查詢進行使用者身份的驗證。在ASP.NET 2.0 中微軟為網頁程式的使用者驗證提供了多種方式,可通過設定檔設定驗證的方式。一般主要使用的是WINDOWS驗證方式和Form驗證方式。
Windows驗證方式有多種驗證技術,但實質上都是對訪問伺服器資源的請求進行驗證,查看請求的頭部資訊中是否包含使用者的身份資訊。當採用Windows驗證方式時,如果伺服器接收到一個不含有使用者資訊的請求時,伺服器會在返回瀏覽器的資訊中標明要求進行驗證。瀏覽器在此情況下會自動彈出遠端使用者登入的對話方塊,要求使用者輸入其在伺服器上的使用者名稱和密碼,或是域中的使用者名稱和密碼。該種驗證方式只能適用於只在內部區域網路中啟動並執行網路應用程式。windows驗證方式下又分為幾種驗證方式,分別是基本驗證,摘要驗證,和windows整合驗證。如果使用windows整合驗證,則瀏覽器自動在發送請求時,自動提供使用者登入網路的身份標識,避免了使用者輸入使用者名稱和密碼的步驟。
Form驗證方式適用於大型的網站,因為在Form驗證方式下,當伺服器接收到未含有使用者身份標識的請求時,自動將該使用者引導到系統登入介面。使用者輸入使用者名稱和密碼後,通過訪問資料庫等驗證方式,驗證該使用者是否為本網站的合法使用者。如果使用者通過驗證,則ASP.NET為該使用者產生表單驗證標籤,並將該標籤發回到用戶端。該標籤一般儲存到COOKIE中或嵌入到URL中。當使用者訪問該網站的其他網頁時,瀏覽器會自動認可該標籤到伺服器,用以記住該使用者。
ASP.NET2.0中的使用者身分識別驗證和使用者權限驗證分別是用兩個內建的HTTPMODULE實現的,它們用於驗證用戶端發送的每一個對該網站資源的請求。使用者身分識別驗證模組驗證瀏覽器提供的使用者身份標籤,如果該請求沒有附帶使用者身份的標籤,則使用者身分識別驗證模組將該使用者標識為匿名使用者;使用者權限驗證用於驗證該使用者是否有訪問指定資源的許可權,如果沒有許可權,則拒絕該請求,並交由使用者身分識別驗證模組處理,身分識別驗證模組會將該使用者引導到登入介面,要求使用者提供具有存取權限的身份標識。
ASP.NET2.0中的使用者權限驗證同樣也分為兩種方式,適用於Windows驗證方式的檔案驗證方式和適用於Form驗證方式的URL驗證方式。檔案驗證方式是通過存取控制列表(ACL)確定不同的WINDOWS賬戶對不同的檔案的儲存許可權。URL驗證方式使用WEB.CONFIG決定不同的使用者和角色對網站中不同的資源的存取權限。
在ASP.NET2.0之前,一般的使用者管理和角色管理都要靠開發人員定義資料庫中關於使用者管理和角色管理的資料表,並自己編寫代碼實現使用者登入,新增使用者,增加角色,系統管理使用者和角色的後台資料庫作業碼。ASP.NET2.0中提供了MEMBERSHIP架構,用於對使用者帳號的管理。 MEMBERSHIP的優點在於該架構提供了一套用於系統管理使用者帳號的介面,但是具體的資料訪問和儲存操作,卻通過PROVIDER來實現,並可根據開發人員的需要配置不同的PROVIDER,用以實現對不同資料來源的操作。 ASP.NET內建了兩個PROVIDER,分別用於對ACTIVE DIRECTORY,和SQL SERVER的儲存訪問。角色管理也同樣採用這種方式,並內建了若干PROVIDER,分別用於對ACTIVE DIRECTORY,和SQL SERVER的儲存訪問以及根據使用者在WINDOWS中的組來進行角色管理(用於WINDOWS驗證模式下)
二.實踐
IIS 身分識別驗證
ASP.NET 身分識別驗證分為兩個步驟。首先,Internet 資訊服務 (IIS) 對使用者進行身分識別驗證,並建立一個 Windows 令牌來表示該使用者。IIS 通過查看 IIS 中繼資料庫設定,確定應該對特定應用程式使用的身分識別驗證模式。如果 IIS 配置為使用匿名驗證,則為 IUSR_MACHINE 帳戶產生一個令牌並用它表示匿名使用者。然後,IIS 將該令牌傳遞給 ASP.NET。
其次,ASP.NET 執行自己的身分識別驗證。所使用的驗證方法由 authentication 元素的 mode 屬性指定。以下身分識別驗證配置指定 ASP.NET 使用 FormsAuthenticationModule 類:
<authentication mode="Forms" />
注 由於表單身分識別驗證不依賴於 IIS 身分識別驗證,因此如果要在 ASP.NET 應用程式中使用表單身分識別驗證,則應該在 IIS 中為應用程式配置匿名訪問。
ASP.NET 表單身分識別驗證
ASP.NET 表單身分識別驗證在 IIS 身分識別驗證完成後發生。可以使用 forms 元素配置表單身分識別驗證。
表單身分識別驗證配置
以下設定檔片段顯示表單身分識別驗證的預設屬性值。
<system.web>
<authentication mode="Forms">
<forms loginUrl="Login.aspx"
protection="All"
timeout="30"
name=".ASPXAUTH"
path="/"
requireSSL="false"
slidingExpiration="true"
defaultUrl="default.aspx"
cookieless="UseDeviceProfile"
enableCrossAppRedirects="false" />
</authentication>
</system.web>
下面是對預設屬性值的描述:
•
loginUrl 指嚮應用程式的自訂登入頁。應該將登入頁放在需要安全通訊端層 (SSL) 的檔案夾中。這有助於確保憑據從瀏覽器傳到 Web 服務器時的完整性。
•
protection 設定為 All,以指定表單身分識別驗證票的保密性和完整性。這導致使用 machineKey 元素上指定的演算法對身分識別驗證票證進行加密,並且使用同樣是 machineKey 元素上指定的雜湊演算法進行簽名。
•
timeout 用於指定表單身分識別驗證會話的有限生存期。預設值為 30 分鐘。如果頒發持久的表單身分識別驗證 Cookie,timeout 屬性還用於設定持久 Cookie 的生存期。
•
name 和 path 設定為應用程式的設定檔中定義的值。
•
requireSSL 設定為 false。該配置意味著身分識別驗證 Cookie 可通過未經 SSL 加密的通道進行傳輸。如果擔心會話竊取,應考慮將 requireSSL 設定為 true。
•
slidingExpiration 設定為 true 以執行變化的會話生存期。這意味著只要使用者在網站上處於活動狀態,會話逾時就會定期重設。
•
defaultUrl 設定為應用程式的 Default.aspx 頁。
•
cookieless 設定為 UseDeviceProfile,以指定應用程式對所有支援 Cookie 的瀏覽器都使用 Cookie。如果不支援 Cookie 的瀏覽器訪問該網站,表單身分識別驗證在 URL 上打包身分識別驗證票。
•
enableCrossAppRedirects 設定為 false,以指明表單身分識別驗證不支援自動處理在應用程式之間傳遞的查詢字串上的票證以及作為某個表單 POST 的一部分傳遞的票證。
授權配置
在 IIS 中,對所有使用表單身分識別驗證的應用程式啟用非同步訪問。UrlAuthorizationModule 類用於協助確保只有經過身分識別驗證的使用者才能訪問頁。
可以使用 authorization 元素配置 UrlAuthorizationModule,如以下樣本所示。
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
使用該設定將拒絕所有未經過身分識別驗證的使用者訪問應用程式中的任何頁。如果未經身分識別驗證的使用者試圖訪問某頁,表單身分識別驗證模組將該使用者重新導向到 forms 元素的 loginUrl 屬性指定的登入頁。
表單身分識別驗證控制流程
•
使用者請求應用程式的虛擬目錄下的 Default.aspx 檔案。因為 IIS 中繼資料庫中啟用了匿名訪問,因此 IIS 允許該請求。ASP.NET 確認 authorization 元素包括 <deny users="?" /> 標記。
•
伺服器尋找一個身分識別驗證 Cookie。如果找不到該身分識別驗證 Cookie,則使用者重新導向到配置好的登入頁 (Login.aspx),該頁由 forms 元素的 LoginUrl 屬性。使用者通過該表單提供和提交憑據。有關起始頁的資訊存放在使用 RETURNURL 作為密鑰的查詢字串中。伺服器 HTTP 應答如下所示:
302 Found Location:
http://localhost/FormsAuthTest/login.aspx?RETURNURL=%2fFormAuthTest%2fDefault.aspx
•
瀏覽器請求 Login.aspx 頁,並在查詢字串中包括 RETURNURL 參數。
•
伺服器返回登入頁以及 200 OK HTTP 狀態碼。
•
使用者在登入頁輸入憑據,並將該頁(包括來自查詢字串的 RETURNURL 參數)發送回伺服器。
•
伺服器根據某個儲存(如 SQL Server 資料庫或 Active Directory 使用者儲存)驗證使用者憑證。登入頁中的代碼建立一個包含為該會話設定的表單身分識別驗證票的 Cookie。
在 ASP.NET 2.0 中,可以通過成員資格系統執行對使用者憑證的驗證。Membership 類為此提供了 ValidateUser 方法,如下所示:
if (Membership.ValidateUser(userName.Text, password.Text))
{
if (Request.QueryString["ReturnUrl"] != null)
{
FormsAuthentication.RedirectFromLoginPage(userName.Text, false);
}
else
{
FormsAuthentication.SetAuthCookie(userName.Text, false);
}
}
else
{
Response.Write("Invalid UserID and Password");
}
注 使用 Login Web 伺服器控制項時,它自動為您執行以下步驟。下文使用了前面提供的代碼。
•
對於經過身分識別驗證的使用者,伺服器將瀏覽器重新導向到查詢字串中的 RETURNURL 參數指定的原始 URL。伺服器 HTTP 應答如下所示:
302 Found Location:
http://localhost/TestSample/default.aspx
•
重新導向之後,瀏覽器再次請求 Default.aspx 頁。該請求包括身分識別驗證 Cookie。
•
FormsAuthenticationModule 類檢測表單身分識別驗證 Cookie 並對使用者進行身分識別驗證。身分識別驗證成功後,FormsAuthenticationModule 類使用有關經過身分識別驗證的使用者的資訊填充當前的 User 屬性(由 HttpContext 對象公開)。
•
由於伺服器已經驗證了身分識別驗證 Cookie,因此它允許訪問並返回 Default.aspx 頁。
FormsAuthenticationModule
ASP.NET 2.0 在電腦級 Web.config 檔案中定義了一組 HTTP 模組,包括大量身分識別驗證模組,如下所示:
<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>
每個請求只能使用一個身分識別驗證模組。所使用的身分識別驗證模組取決於 authentication 元素(通常位於應用程式的虛擬目錄中的 Web.config 檔案中)指定了哪種身分識別驗證模式。
當 Web.config 檔案中包含以下元素時,啟用 FormsAuthenticationModule 類。
<authentication mode="Forms" />
FormsAuthenticationModule 類構造一個 GenericPrincipal 對象並將其儲存在 HTTP 上下文中。GenericPrincipal 對象儲存對一個 FormsIdentity 執行個體的引用,該執行個體代表當前經過身分識別驗證的使用者。應該允許表單身分識別驗證為您管理這些任務。如果應用程式有特定要求(例如,將 User 屬性設定為一個實現 IPrincipal 介面的自訂類),則該應用程式應該處理 PostAuthenticate 事件。FormsAuthenticationModule 驗證了表單身分識別驗證 Cookie 並建立了 GenericPrincipal 和 FormsIdentity 對象之後,會發生 PostAuthenticate 事件。在該代碼中,可以構造一個封裝 FormsIdentity 對象的自訂 IPrincipal 對象,然後將它儲存在 HttpContext. User 屬性中。
注 如果執行了這一操作,還需要設定 Thread.CurrentPrincipal 屬性上的 IPrincipal 引用,以確保 HttpContext 對象和該線程指向相同的身分識別驗證資訊。
表單身分識別驗證 Cookie
調用 FormsAuthentication.SetAuthCookie 或FormsAuthentication.RedirectFromLoginPage 方法時,FormsAuthentication 類自動建立身分識別驗證 Cookie。
典型的表單身分識別驗證 Cookie 中包括以下屬性:
•
Name。該屬性指定 Cookie 的名稱。
•
Value。該屬性指定 Cookie 的值。
在典型的表單身分識別驗證 Cookie 中,該值包含一個經過加密和簽名的 FormsAuthenticationTicket 對象的字串表示形式。該 Cookie 包含以下屬性:
•
Expires。該屬性指定 Cookie 的到期日和時間。僅當代碼指示應該頒發一個持久的表單身分識別驗證 Cookie,表單身分識別驗證才設定該值。
•
Domain。該屬性指定與 Cookie 關聯的域。預設值為 null。
•
HasKeys。該屬性指出 Cookie 是否有子項。
•
HttpOnly。該屬性指定是否可以通過用戶端指令碼訪問該 Cookie。在 ASP.NET 2.0 中,該值始終設定為 true。Internet Explorer 6 Service Pack 1 支援該 Cookie 屬性,從而防止用戶端指令碼從 document.cookie 屬性訪問該 Cookie。如果嘗試從用戶端指令碼訪問該 Cookie,則返回一個Null 字元串。無論何時使用者瀏覽到當前域中的 Web 網站,該 Cookie 仍然發送至伺服器。
注 不支援 HttpOnly Cookie 屬性的 網頁瀏覽器要麼忽略該 Cookie,要麼忽略該屬性,這意味著會話仍然容易受到跨網站指令碼的攻擊。
•
Path。該屬性指定 Cookie 的虛擬路徑。預設值為"/",代表根目錄。
•
Secure。該屬性指出 Cookie 是否應該僅通過 HTTPS 串連傳輸。Secure 屬性應設定為 true,以便該 Cookie 可以受 SSL 加密的保護。
•
Version。該屬性指定 Cookie 的版本號碼。
建立身分識別驗證 Cookie
通過 FormsAuthentication 類建立身分識別驗證 Cookie,如下所示。使用者經過驗證後,FormsAuthentication 類在內部建立一個 FormsAuthenticationTicket 對象,方法是指定 Cookie 名、Cookie 版本、目錄路徑、Cookie 頒發日期;Cookie 到期日、是否應該保留 Cookie,以及使用者定義的資料(可選)。
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
"userName",
DateTime.Now,
DateTime.Now.AddMinutes(30), // value of time out property
false, // Value of IsPersistent property
String.Empty,
FormsAuthentication.FormsCookiePath);
接下來,如果 forms 元素的 protection 屬性設定為 All 或 Encryption,則表單身分識別驗證使用 Encrypt 方法對表單身分識別驗證票進行加密和簽名。
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
以下文本顯示了當 protection 屬性設定為 All 時使用的過程:
•
建立序列化表單身分識別驗證票。建立票證的位元組數組表示形式。
•
對表單身分識別驗證票進行簽名。位元組數組的訊息身分識別驗證代碼 (MAC) 的值,由使用 machineKey 元素的 validation 和 validationKey 屬性指定的演算法和密鑰進行計算。預設情況下,使用 SHA1 演算法。
•
對表單身分識別驗證票進行加密。已經建立的第二個位元組數組使用 FormsAuthentication 類的 Encrypt 方法進行加密。該 Encrypt 方法在內部使用由 machineKey 元素上的 decryption 和 decryptionKey 屬性指定的演算法和密鑰。ASP.NET 1.1 版在預設情況下使用 3DES 演算法。ASP.NET 2.0 版在預設情況下使用 Rinjdael (AES) 演算法。
•
根據需要建立 HTTP Cookie 或查詢字串。然後,如果表單身分識別驗證針對 cookieless 身分識別驗證進行了配置,則加密的身分識別驗證票添加到 HttpCookie 對象。使用以下代碼建立該 Cookie 對象:
HttpCookie authCookie = new HttpCookie(
FormsAuthentication.FormsCookieName,
encryptedTicket);
•
將表單身分識別驗證Cookie 設定為安全的。如果表單身分識別驗證票配置為使用 SSL,則 HttpCookie.Secure 屬性設定為 true。這表明瀏覽器僅通過 HTTPS 串連發送 Cookie。
authCookie.Secure = true;
•
設定 HttpOnly 位。在 ASP.NET 2.0 中,始終設定該位。
•
設定適當的 Cookie 屬性。如果需要,設定 Cookie 的 path、domain 和 expires 屬性。
•
將 Cookie 添加到 Cookie 集合。將身分識別驗證 Cookie 添加到要返回給用戶端瀏覽器的 Cookie 集合。
Response.Cookies.Add(authCookie);
每次在身分識別驗證之後接收一個後續請求時,FormsAuthenticationModule 類都會從身分識別驗證 Cookie 中檢索身分識別驗證票,對其進行解密,計算雜湊值,並比較該 MAC 值,以協助確保該 Cookie 未被篡改。最後,驗證該表單身分識別驗證票中包含的到期時間。
注 ASP.NET 並不依賴於 Cookie 的到期日,因為該時間很容易偽造。
角色授權
在 ASP.NET 2.0 中,角色授權已經得到簡化。對使用者進行身分識別驗證或者將角色細節添加到身分識別驗證 Cookie 時,不再需要檢索角色資訊。.NET Framework 2.0 包括一個角色管理 API,它使您能夠建立和刪除角色,將使用者添加到角色以及從角色刪除使用者。該角色管理 API 將其資料存放區在一個基礎資料存放區中,它通過針對該資料存放區的適當角色提供者訪問該儲存。以下角色提供者為 .NET Framework 2.0 附帶,可以與表單身分識別驗證一起使用:
•
SQL Server。它是預設的提供者,將角色資訊儲存在 SQL Server 資料庫。
•
授權管理員 (AzMan)。 該提供者使用 XML 檔案、Active Directory 或 Active Directory 應用程式模式 (ADAM) 中的一個 AzMan 策略儲存作為其角色儲存。它通常用於 Intranet 或 Extranet 方案中,其中 Windows 身分識別驗證和 Active Directory 用於進行身分識別驗證。
有關如何使用角色管理 API 的詳細資料,請參閱 How To: Use Role Manager in ASP.NET 2.0。
Cookieless 表單身分識別驗證
ASP.NET 2.0 支援 cookieless 表單身分識別驗證。該功能由 forms 元素的 cookieless 屬性控制。該屬性可以設定為以下四個值之一:
•
UseCookies。該值強制 FormsAuthenticationModule 類使用 Cookie 傳輸身分識別驗證票。
•
UseUri。該值指示 FormsAuthenticationModule 類重寫 URL 來傳輸身分識別驗證票。
•
UseDeviceProfile。該值指示 FormsAuthenticationModule 類查看瀏覽器功能。如果瀏覽器支援 Cookie,則使用 Cookie;否則,重寫 URL。
•
AutoDetect。該值通過一個動態檢測機制指示 FormsAuthenticationModule 類檢測瀏覽器是否支援 Cookie。如果檢測邏輯表明不支援 Cookie,則重寫 URL。
如果應用程式配置為使用 cookieless 表單身分識別驗證,並且正在使用 FormsAuthentication.RedirectFromLoginPage 方法,則 FormsAuthenticationModule 類自動化佈建 URL 中的表單身分識別驗證票。以下程式碼範例顯示了典型 URL 在重寫後的外觀:
http://localhost/CookielessFormsAuthTest/(F(-k9DcsrIY4CAW81Rbju8KRnJ5o_gOQe0I1E_jNJLYm74izyOJK8GWdfoebgePJTEws0Pci7fHgTOUFTJe9jvgA2))/Test.aspx
括弧中的 URL 部分包含 Cookie 通常將包含的資料。該資料在請求處理過程中由 ASP.NET 刪除。該步驟由 ASP.NET ISAPI 篩選器執行,而不是在 HttpModule 類中執行。如果從一個 .aspx 頁讀取 Request.Path 屬性,您在 URL 中不會看到任何額外的資訊。如果重新導向請求,URL 將自動重寫。
注 難以保證 URL 中包含的身分識別驗證票的安全。當安全性極為重要時,您應該使用 Cookie 儲存身分識別驗證票。
成員資格和登入控制項
ASP.NET 2.0 引入了成員資格功能和一組登入 Web 伺服器控制項,它們簡化了使用表單身分識別驗證的應用程式的實現。
成員資格為應用程式使用者提供憑據儲存和管理。它還提供一個成員資格 API,可以在使用表單身分識別驗證時簡化使用者憑證的驗證任務。該成員資格功能構建於提供者模型之上。該模型允許實現和配置指向不同使用者儲存的不同提供者。ASP.NET 2.0 包括以下成員關係提供者:
•
Active Directory 成員關係提供者。該提供者使用 Active Directory 或 Active Directory 應用程式模式 (ADAM) 使用者儲存。
•
SQL Server 成員關係提供者。該提供者使用 SQL Server 使用者儲存。
還可以添加對自訂使用者儲存的支援。例如,可以添加對其他輕量級目錄訪問協議 (LDAP) 目錄或其他現有公用標識儲存的支援。為此,建立一個從 MembershipProvider 抽象基類繼承的自訂提供者。
ASP.NET 登入控制項自動使用成員資格和表單身分識別驗證,並封裝提示使用者輸入憑據,驗證使用者,恢複或替換密碼等所需的邏輯。實際上,ASP.NET 登入控制項在表單身分識別驗證和成員資格上提供一個抽象層,並且取代了您使用表單身分識別驗證時通常必須進行的大多數或全部工作。
原文連結:http://edu.itbulo.com/200607/101618.htm