ASP.NET安全問題--Forms驗證實戰(zhàn)篇
前言:通過之前的幾篇文章,相信大家對Forms驗證有了一定的了解,也清楚了Identity,IPrincipal,票據(jù)等概念。之前的文站一直沒有把驗證和數(shù)據(jù)庫聯(lián)系起來,本篇就從這方面講解,用代碼來演示!而且代碼中也涉及到一些角色授權(quán)的問題,為之后的文章伏筆! 驗證流程講述 驗證流程講述
我們首先假設(shè)一個場景:用戶現(xiàn)在已經(jīng)打開了我們的首頁Default.aspx,但是有些資源只能是登錄用戶才可以看到的,那么如果這個用戶想要查看這些資源,那么他就要登錄。而且這個用戶已經(jīng)有了一個賬號。(我們本篇主要的話題是身份驗證,至于創(chuàng)建用戶賬戶是怎么創(chuàng)建的,我們不關(guān)心,方法很多,如直接一個數(shù)據(jù)庫插入就行了!) 數(shù)據(jù)庫準(zhǔn)備 那么下面我們就開始詳細(xì)講述: ![]() ![]() public static bool ValidateUser(string username, string password) {驗證代碼 SqlConnection con = new SqlConnection(); con.ConnectionString = ConfigurationManager.ConnectionStrings[“MyConnectionString”].ConnectionString; SqlCommand com = new SqlCommand(); com.Connection = con; com.CommandText = “Select Count(*) From Users Where Username=@Username and UserPassword=@Password”; com.Parameters.AddWithValue(“@Username”, username); com.Parameters.AddWithValue(“@Password”, password); con.Open(); int cnt = (int)com.ExecuteScalar(); con.Close(); return (cnt > 0); } 然后我們就創(chuàng)建一個登錄的頁面Login.aspx,在頁面上面放入兩個TextBox,分別用來供用戶輸入用戶名和密碼。
放上一個按鈕,用來登錄。
回到Helpers.cs中,我再添加一個方法,來獲取用戶的角色:
![]() ![]() public static string GetRoleForUser(string username ) { //創(chuàng)建鏈接 SqlConnection con = new SqlConnection(); con.ConnectionString = ConfigurationManager.ConnectionStrings[“MyConnectionString”].ConnectionString; SqlCommand com = new SqlCommand(); com.Connection = con; //執(zhí)行命令 com.CommandText = “Select UseRole m Users Where Username=@Username; com.Parameters.AddWithValue(“@Username”, username); con.Open(); //返回結(jié)果 string userRole= (string)com.ExecuteScalar(); con.Close(); }Code 為了啟動Forms驗證,我們還得到web.config文件中配置,如下:
<authentication mode=”Forms”>
<forms name=”.mycookie” path=”/” loginUrl=”Login.aspx” protection=”All” timeout=”40” /> </authentication> 并且不允許匿名用戶訪問我們的網(wǎng)站 :
<authorization>
<deny users=”?”/> </authorization> 然后我們就開始在Login.aspx的登錄按鈕下面寫代碼了:
基本思想如下:
1.驗證用戶是否存在,
2.如果存在,同時獲取用戶的角色
3.創(chuàng)建身份驗證票據(jù)和cookie,并且發(fā)送到客戶端的瀏覽器中
代碼都加了注釋,通過之前的基礎(chǔ),相信大家可以對下面的代碼沒有問題。
![]() ![]() Code protected void LoginCallback(object sender, EventArgs e) { if (Helpers.ValidateUser(UserName.Text, Password.Text)) { //獲取用戶的角色 string rolenames = Helpers.GetRolesForUser(UserName.Text); //創(chuàng)建身份驗證票據(jù) FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, UserName.Text, DateTime.Now, DateTime.Now.AddSeconds(40), false, roles); //加密票據(jù) string encryptedTicket = FormsAuthentication.Encrypt(ticket); //創(chuàng)建新的cookie HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName); //把加密后的票據(jù)信息放入cookie cookie.Value = encryptedTicket; //把cookie添加到響應(yīng)流中 Response.Cookies.Add(cookie); //把cookie發(fā)送到客戶端 Response.Redirect(FormsAuthentication.GetRedirectUrl(UserName.Text,false),true); } }Code 好了,現(xiàn)在如果我們正確的輸入用戶名和密碼,那么我們的瀏覽器中就有了身份驗證的cookie了,現(xiàn)在我們的頁面就要馬上從原來的Login.aspx轉(zhuǎn)向到Default.aspx頁面了,我們現(xiàn)在把這個轉(zhuǎn)向的過程在頭腦中把它慢速化,因為我們要分析這個過程。
在Login.aspx轉(zhuǎn)向到Default.aspx頁面跳轉(zhuǎn)的過程中,其實我們在請求Default.aspx頁面,這個我們之前請求的過程沒有任何的區(qū)別,也是一樣要經(jīng)歷ASP.NET的一些生命周期,但是這次我們的瀏覽器中已經(jīng)有了身份驗證的cookie,ASP.NET運行時在處理,在處理Application_AuthenticateRequest事件時就要解析我們的cookie了。其實在之前我們登錄之前,在這個事件代碼中也解析了cookie的,只是那時候沒有找到cookie而以。 Application_AuthenticateRequest事件的代碼中,其實就是解析cookie,然后把用戶的身份標(biāo)識,并且把用戶的身份信息保存起來: ![]() ![]() Code Code void Application_AuthenticateRequest(object sender, EventArgs e) { HttpApplication app = (HttpApplication)sender; //獲取身份驗證的cookie HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName]; if (cookie != null) { string encryptedTicket = cookie.Value; //解密cookie中的票據(jù)信息 FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encryptedTicket); //獲取用戶角色信息 string[] roles = new string[]{ticket.UserData.toString()}; //創(chuàng)建用戶標(biāo)識 FormsIdentity identity = new FormsIdentity(ticket); //創(chuàng)建用戶的主體信息 System.Security.Principal.GenericPrincipal user = new System.Security.Principal.GenericPrincipal(identity, roles); app.Context.User = user; } }Code 我們看到最后一行代碼:app.Context.User = user;,把用戶的身份以及角色信息保存在了User屬性中。
我們就可以在頁面中通過如下方法判斷用戶是否登錄了:
if (Page.User.Identity.IsAuthenticated)
{ // ![]() } 用下面的方法判斷用戶是否屬于某個角色:
if (Page.User.IsInRole("Admin")
{ // ![]() } 原文出處: http://www.cnblogs.com/yanyangtian/archive/2009/06/01/1493722.html
標(biāo)簽: asp.net安全
|
|
來自: 昵稱10504424 > 《工作》