asp身份驗證問題
<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 屬性指定的登入頁。 窗體身份驗證控制流 圖 1 顯示窗體身份驗證期間出現的事件順序。 圖 1. 窗體身份驗證控制流
· | 使用者請求應用程式的虛擬目錄下的 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 頁。 |
<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。
|
||
· | HttpOnly。該屬性指定是否可以通過客戶端指令碼訪問該 Cookie。在 ASP.NET 2.0 中,該值始終設定為 true。Internet Explorer 6 Service Pack 1 支援該 Cookie 屬性,從而防止客戶端指令碼從 document.cookie 屬性訪問該 Cookie。如果嘗試從客戶端指令碼訪問該 Cookie,則返回一個空字串。無論何時使用者瀏覽到當前域中的 Web 站點,該 Cookie 仍然傳送至伺服器。 注 不支援 HttpOnly Cookie 屬性的 Web 瀏覽器要麼忽略該 Cookie,要麼忽略該屬性,這意味著會話仍然容易受到跨站點指令碼的攻擊。 | ||
· | Path。該屬性指定 Cookie 的虛擬路徑。預設值為"/",代表根目錄。 | ||
· | Secure。該屬性指出 Cookie 是否應該僅通過 HTTPS 連線傳輸。Secure 屬性應設定為 true,以便該 Cookie 可以受 SSL 加密的保護。 | ||
· | Version。該屬性指定 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); |
角色授權 在 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 用於進行身份驗證。 |
· | UseCookies。該值強制 FormsAuthenticationModule 類使用 Cookie 傳輸身份驗證票。 |
· | UseUri。該值指示 FormsAuthenticationModule 類重寫 URL 來傳輸身份驗證票。 |
· | UseDeviceProfile。該值指示 FormsAuthenticationModule 類檢視瀏覽器功能。如果瀏覽器支援 Cookie,則使用 Cookie;否則,重寫 URL。 |
· | AutoDetect。該值通過一個動態檢測機制指示 FormsAuthenticationModule 類檢測瀏覽器是否支援 Cookie。如果檢測邏輯表明不支援 Cookie,則重寫 URL。 |
http://localhost/CookielessFormsAuthTest/(F(-k9DcsrIY4CAW81Rbju8KRnJ5o_gOQe0I1E_jNJLYm74izyOJK8GWdfoebgePJTEws0 _Pci7fHgTOUFTJe9jvgA2))/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 使用者儲存。 |