補充: 12:39 2004-7-11
最近閱讀了Wrax版的《ASP.NET安全性進階編程》,裡面涉及了基於Forms的驗證,發現自己有很多誤解,於是決定對《ASP.NET基於表單的驗證實現網上安全訪問,管理》一文補充與更正.
檔案目錄為:
+BIN
+Admin
-index.aspx
- test.aspx
- *.aspx
- web.config //Admin檔案夾下的web.config
login.aspx
web.config //根目錄的web.config
index.aspx
(-)看看FormsAuthentication的重要方法以及屬性(更多search MSDN)
FormsCookieName
返回用於當前應用程式的已配置 Cookie 名稱。
GetAuthCookie
為給定的使用者名稱建立身分識別驗證 Cookie。這不會將 Cookie 設定為傳出響應的一部分,因此應用程式對如何發出該 Cookie 有更多的控制許可權。
Authenticate
給定所提供的憑據,嘗試根據包含在已配置憑據儲存區中的憑據對憑據進行驗證。
GetRedirectUrl
返回導致重新導向到登入頁的原始請求的重新導向 URL。
HashPasswordForStoringInConfigFile
給定標識雜湊類型的密碼和字串,該常式產生一個適合儲存在設定檔中的雜湊密碼。
RedirectFromLoginPage
將已驗證身份的使用者重新導向回最初請求的 URL。
{=========
備忘
RedirectFromLoginPage 方法重新導向到在查詢字串中指定的返回 URL 鍵。例如,在 URL http://www.contoso.com/login.aspx?ReturnUrl=caller.aspx 中,caller.aspx 是 RedirectFromLoginPage 所重新導向到的返回 URL。如果返回鍵不存在,則 RedirectFromLoginPage 將重新導向到 Default.aspx。
=========}
SetAuthCookie
建立身分識別驗證票並將其附加到 Cookie 的傳出響應的集合。它不執行重新導向。
SignOut
移除身分識別驗證票.
(二)讓我們一步一步徹底明白頁面是怎樣驗證的
再次說明我們驗證的目的:
Admin檔案夾是管理員進行後台管理的"專區",只有通過login.aspx登陸驗證後才能進入Admin檔案夾裡面訪問裡面的所有頁面,所有,我們必須通過填寫login.aspx的表單來驗證使用者是否是管理員.
(1) 假設我們在根目錄的index.aspx設定一個串連<a href=login.aspx>管理員登陸</a>,管理員可以通過這個串連,訪問login.aspx進行填寫表單.這裡出現了一個奇妙的思維定勢的問題,我們習慣這個"管理員登陸"串連來串連到login.aspx,其實在這裡,我們錯了,應該"直接"串連到Admin檔案夾(或者裡面的任何頁面),有人問:"這豈不是普通訪問者也可以通過這個串連直接連接到了Admin的頁面了嗎?",我說:"對!,這就是基於表單驗證的美妙之處,不用擔心這個問題,看看我們的2個web.config就明白了!".
看看Admin檔案夾裡面的web.config
<configuration>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
有一個<deny users="?"/>,就是說沒有通過驗證的匿名使用者絕對禁止訪問這個檔案夾-Admin.
那麼,如果匿名使用者真的這樣做了(試圖串連Admin檔案夾裡面的頁面)會怎樣呢?哈哈,會定向到login.aspx頁面的,看看根目錄的web.config
<configuration>
<system.web>
<authentication mode="Forms">
<forms name="mycookiename" loginUrl="login.aspx" protection="All" timeout="30">
</forms>
</authentication>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</configuration>
根目錄的web.config設定了驗證方式,以及相應的處理情況.
<authentication mode="Forms">來設定了驗證方式mode="Forms";
<forms name="mycookiename" loginUrl="login.aspx" protection="All" timeout="30"/>
看到了loginurl="login.aspx"了嗎?就是說,如果匿名使用者試圖串連受保護的頁面(Admin檔案夾),則定向到login.aspx,來讓這個匿名使用者登陸!
(2)我們點擊了那個"管理員登陸"連結,來到了login.aspx.此時你會發現,URL地址其實是:login.asxp?ReturnUrl=admin/index.asp(其實就是我們所請求的頁面),如果我們在login.asxp通過了驗證,那麼,頁面會自動跳轉到那個ReturnUrl.
看看login.axp:
<asp:textbox id=textname runat=server/>帳號
<asp:textpassword id=textpassword runat=server>密碼
<asp:checkbox id=mycheckbox runat=server/>是否記住密碼,永久登陸
<asp:button runat=server onclick=btnloginclick text=登陸/>
處理事件1(當使用者點擊登陸按鈕時候)
void btnloginclick(Object sender,EventArgs e)
{
if(使用者通過驗證)//這一點可以在bin目錄放置自己的dll檔案來驗證使用者,返回一個bool.
{
FormsAuthentication.RedirectFromLoginPage(UserName.Text, mycheckbox.Checked);
}
}
1,FormsAuthentication.RedirectFromLoginPage(UserName.Text, mycheckbox.Checked);的作用:
->設定一個驗證Cookie,說明使用者已經通過驗證.
->返回剛才您所請求的頁面(Admin/index.aspx);
2,這句話相當於這兩句:
FormsAuthentication.SetAuthCookie(UserName.Text,mycheckbox.Checked);
Response.Redirect(FormsAuthentication.GetRedirectUrl(UserName.Text,mycheckbox.Checked);
3,如果mycheckboxt控制項已經選擇,則,寫入cookie,儲存50年,當然,我們可以更改這個時間:
處理事件1(當使用者點擊登陸按鈕時候)
void btnloginclick(Object sender,EventArgs e)
{
if(使用者通過驗證)//這一點可以在bin目錄放置自己的dll檔案來驗證使用者,返回一個bool.
{
HttpCookie authenticationCookie=FormsAuthentication.GetAuthcookie(UserName.Text,mycheckbox.Checked);
authenticationCookie.Expires=DateTime.Now.AddDays(3);//3天
Response.Cookies.Add(authenticationCookie);
Response.Redirect(FormsAuthentication.GetRedirectUrl(UserName.Text,mycheckbox.Checked);
}
4,這裡有個bug,我不知道為什麼會這樣,我們這樣:
處理事件1(當使用者點擊登陸按鈕時候)
void btnloginclick(Object sender,EventArgs e)
{
if(使用者通過驗證)//這一點可以在bin目錄放置自己的dll檔案來驗證使用者,返回一個bool.
{
FormsAuthentication.RedirectFromLoginPage(UserName.Text, mycheckbox.Checked);
Response.Redirect("http://www.QuickResponser.com");
}
}
會怎樣呢?按理說應該執行FormsAuthentication.RedirectFromLoginPage(UserName.Text, mycheckbox.Checked);
然後跳轉到請求的頁面admin/index.aspx.
可是,我在實際實驗過程中,發現頁面執行了Response.Redirect("http://www.QuickResponser.com");
oh,mygod!!!!,鬱悶(誰給我個正確的解釋呢?QQ:154222225 Mail:root@3ney.com);
5,我們的連結不要涉及到直接連接到login.aspx,為什麼?假設我們直接登陸login.asxp,那麼這個URL就沒有參數ReturnUrl,但是,預設是Default.aspx(或者index.axp....),當管理員通過驗證時候,頁面不是直接跳轉到根目錄的預設頁面index.aspx.
(如果直接連接的話,也是可以的,利用上面的bug解決)
參考:
1,《ASP.NET進階編程》--Wrax
2,《ASP.NET安全性進階編程》--Wrax
=============================
廢話很多,希望大家能看明白.
基於表單的驗證涉及的其他問題:
1,無Cookie的驗證
2,驗證資料的儲存方式
3,基於角色的表單驗證