天天看點

Forms驗證中的roles

一直對forms驗證中的角色很模糊,不知道怎麼搞,昨天晚上仔細看了下csdn的雜志,心裡稍微有點底,今天早晨一上csdn,就看到思歸大人回的一篇貼,是關于asp.net中的forms驗證roles,位址是:http://www.codeproject.com/aspnet/formsroleauth.asp

汗,怎麼是E文,我的e文特差,但是不知道為什麼這次竟然被我看懂了,模仿他的做,竟然成功!,特把過程以及我的了解寫出來,希望對和我一樣的菜鳥有點幫助,同時我的一些了解可能錯誤,希望各位老大們能夠指出,非常感謝,下面我開始邊翻譯邊按照他的做:

1,首先我們建立一個資料庫,名字叫web,添加一個表叫users,裡面有三個字段,username字段為主鍵,username和password字段設定為聯合索引,不知道我這樣了解對麼?請指正

CREATE

DATABASE web

CREATE TABLE users

(

username nvarchar(64) CONSTRAINT users_PK PRIMARY KEY,

password nvarchar(128),

roles nvarchar(64)

)

CREATE INDEX credentials ON users

(

username,

password

)

我們再在users表中添加兩個使用者:pwqzc  123456  Administrator,User

                              pwq    123456  User

第一個為名字,第二個為密碼,第三個為使用者所具有的角色,多個角色用,逗号分開

2,建立一個登陸頁login.aspx

裡面放兩個TextBox和一個按鈕,在按鈕的單擊事件裡寫代碼:

private void btnLogin_Click(object sender, System.EventArgs e)

{

//初始化FormsAuthentication

FormsAuthentication.Initialize();

//建立個connection和command對象

            SqlConnection conn = new SqlConnection("server=(local);uid=sa;pwd=mydream54win;database=web");

SqlCommand cmd = conn.CreateCommand();

cmd.CommandText = "select roles from users where [email protected] and [email protected]";

//添加參數以及給參數指派

cmd.Parameters.Add("@username",SqlDbType.VarChar,64);

cmd.Parameters["@username"].Value = Username.Value;

cmd.Parameters.Add("@password",SqlDbType.VarChar,128);

cmd.Parameters["@password"].Value = Password.Value;

            //打開資料庫連接配接

conn.Open();

//執行指令

SqlDataReader reader = cmd.ExecuteReader();

if(reader.Read())

{

//建立一個新的驗證票FormsAuthenticationTicket

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(

1,//票版本号

Username.Value,//cookie名字

DateTime.Now,//生成cookie時間

DateTime.Now.AddMinutes(30),//cookie的有效時間

false,//是不是永久存在的cookie

reader.GetString(0));//從資料庫讀到的使用者角色資料

//把驗證票加密

string hashTicket = FormsAuthentication.Encrypt(ticket);

//設定驗證票cookie,第一個參數為cookie的名字,第二個參數為cookie的值也就是加密後的票

HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,hashTicket);

//設定cookie的有效期是一個禮拜

cookie.Expires = DateTime.Now.AddDays(7);

//把cookie加進Response對象發生到用戶端

Response.Cookies.Add(cookie);

//得到請求的url

string requestUrl = FormsAuthentication.GetRedirectUrl(FormsAuthentication.FormsCookieName,false);

//不要使用FormsAuthentication.RedirectFromLoginPage方法,因為這個方法會重寫cookie

//重新定向到請求的url

Response.Redirect(requestUrl);

}

else

{

    //如果不存在此使用者,則提示一些錯誤

ErrorLabel.Text = "使用者名或者密碼錯誤,請重試!";

ErrorLabel.Visible = true;

}

//關閉資料庫連接配接和reader

reader.Close();

conn.Close();

}

3,第三步,在應用程式的Global.asax中,找到Application_AuthenticateRequest,寫下面代碼,記的要導入using System.Security.Principal;

using System.Web.Security;這兩個名字空間,代碼如下:

protected void Application_AuthenticateRequest(Object sender,EventArgs e)

{

if(HttpContext.Current.User!=null)//如果目前的http資訊中存在使用者資訊

{

if(HttpContext.Current.User.Identity.IsAuthenticated)//如果目前使用者的身份已經通過了驗證

{

if(HttpContext.Current.User.Identity is FormsIdentity)

{

    //如果目前使用者身份是FormsIdentity類即窗體驗證類,此類有個屬性能夠通路目前使用者的驗證票

FormsIdentity fi = (FormsIdentity)HttpContext.Current.User.Identity;//建立個FormsIdentity類,用他來通路目前使用者的驗證票

                        //獲得使用者的驗證票

FormsAuthenticationTicket ticket = fi.Ticket;

//從驗證票中獲得使用者資料也就是角色資料

string userData = ticket.UserData;

//把使用者資料用,分解成角色數組

string[] roles = userData.Split(',');

//重寫目前使用者資訊,就是把角色資訊也加入到使用者資訊中

HttpContext.Current.User = new GenericPrincipal(fi,roles);

}

}

}

}

4,第四步,修改web.config

<configuration>

<system.web>

<authentication mode="Forms">

<forms name="MYWEBAPP.ASPXAUTH"

loginUrl="login.aspx"

protection="All"

path="/"/>

</authentication>

<authorization>

<allow users="*"/>

</authorization>

</system.web>

<location path="admins">

<system.web>

<authorization>

<!-- Order and case are important below -->

<allow roles="Administrator"/>

<deny users="*"/>

</authorization>

</system.web>

</location>

<location path="users">

<system.web>

<authorization>

<!-- Order and case are important below -->

<allow roles="User"/>

<deny users="*"/>

</authorization>

</system.web>

</location>

</configuration>

5,測試,在應用程式下建立兩個目錄admins和users,分别在他們的目錄下放個default.aspx,上面随便寫些什麼東西,把其中的一個default.aspx設定問起始頁(在vs2003環境下),如果你輸入名字pwq和密碼是不能夠進入admins目錄下的,因為這個使用者不屬于Administrator角色!

 我們來看下Forms身份驗證基本原理:

一 身份驗證

要采用Forms身份驗證,先要在應用程式根目錄中的Web.config中做相應的設

置:

<authentication mode="Forms">

    <forms name=".ASPXAUTH" loginUrl="login.aspx" timeout="30"

path="/"/>

</authentication>

其中<authentication mode="Forms"> 表示本應用程式采用Forms驗證方

式。

<forms>标簽中的name表示指定要用于身份驗證的Cookie。預設是.ASPXAUTH,其實你可以用任何名字,這也就是你在本地硬碟上看到的cookie裡面的前面的幾個字.

Forms的驗證過程如下:1,生成身份驗證票,2,加密身份驗證票.3,寫回用戶端,4,浏覽器重新定向.其實這一系列的動作如果我們不用roles的話都是通過FormsAuthentication.RedirectFromLoginPage方法來完成了這一系列的工作任務.但是既然我們要使用roles授權,我們就不能夠使用這個方法,而要分開來,一步步完成.

首先是建立身份驗證票,首先我們看看FormsAuthenticationTicket類的一個構造函數:

public FormsAuthenticationTicket(

int version, //設為1

string name, //使用者标示

DateTime issueDate, //Cookie 的發出時間, 設定為 DateTime.Now

DateTime expiration, //過期時間

bool isPersistent, //是否持久性(根據需要設定,若是設定為持久性,在發出

cookie時,cookie的Expires設定一定要設定)

string userData, //這裡用上面準備好的用逗号分割的role字元串

string cookiePath // 設為”/”,這要同發出cookie的路徑一緻,因為重新整理cookie

要用這個路徑

);

最後個參數可以省略

FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket

(1,”kent”,DateTime.Now, DateTime.Now.AddMinutes(30), false,UserRoles)

 我們來看下Forms身份驗證基本原理:

一 身份驗證

要采用Forms身份驗證,先要在應用程式根目錄中的Web.config中做相應的設

置:

<authentication mode="Forms">

    <forms name=".ASPXAUTH" loginUrl="login.aspx" timeout="30"

path="/"/>

</authentication>

其中<authentication mode="Forms"> 表示本應用程式采用Forms驗證方

式。

<forms>标簽中的name表示指定要用于身份驗證的Cookie。預設是.ASPXAUTH,其實你可以用任何名字,這也就是你在本地硬碟上看到的cookie裡面的前面的幾個字.

Forms的驗證過程如下:1,生成身份驗證票,2,加密身份驗證票.3,寫回用戶端,4,浏覽器重新定向.其實這一系列的動作如果我們不用roles的話都是通過FormsAuthentication.RedirectFromLoginPage方法來完成了這一系列的工作任務.但是既然我們要使用roles授權,我們就不能夠使用這個方法,而要分開來,一步步完成.

首先是建立身份驗證票,首先我們看看FormsAuthenticationTicket類的一個構造函數:

public FormsAuthenticationTicket(

int version, //設為1

string name, //使用者标示

DateTime issueDate, //Cookie 的發出時間, 設定為 DateTime.Now

DateTime expiration, //過期時間

bool isPersistent, //是否持久性(根據需要設定,若是設定為持久性,在發出

cookie時,cookie的Expires設定一定要設定)

string userData, //這裡用上面準備好的用逗号分割的role字元串

string cookiePath // 設為”/”,這要同發出cookie的路徑一緻,因為重新整理cookie

要用這個路徑

);

最後個參數可以省略

FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket

(1,”kent”,DateTime.Now, DateTime.Now.AddMinutes(30), false,UserRoles)

然後加密:

string hashTicket = FormsAuthentication.Encrypt(ticket);

//設定驗證票cookie,第一個參數為cookie的名字,第二個參數為cookie的值也就是加密後的票

HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,hashTicket);

//設定cookie的有效期是一個禮拜

cookie.Expires = DateTime.Now.AddDays(7);

//把cookie加進Response對象發生到用戶端

Response.Cookies.Add(cookie);

//得到請求的url

string requestUrl = FormsAuthentication.GetRedirectUrl(FormsAuthentication.FormsCookieName,false);

//不要使用FormsAuthentication.RedirectFromLoginPage方法,因為這個方法會重寫cookie

//重新定向到請求的url

Response.Redirect(requestUrl);

以後的各個頁面中通過HttpContext.Current.User.Identity.Name判斷使用者辨別,

  HttpContext.Current.User.IsInRole("Admin")判斷使用者是否屬于某一角色(或某一組)