一個Form驗證的方案
asp.net自己帶了一個可以自動生成認證的類,但這個FormsAuthentication自動的Cookie除了包含認證票據以外,不能自己帶其它的資料。
而對於一個專案來說,可能要對瀏覽者進行不同型別的驗證,而對於asp的寫法來說,就是用session來驗證。我不喜歡這樣的方法,而且這樣的話也就不能實現自動登入了。
還好,.net裡帶了一個可以自己定義票據的方法,這樣我們一方面可以進行自動登入,另一方面還可以對不用的使用者進行驗證。下面是一個生成票據的程式碼:
public virtual void Login(bool i_autoLogin)
{
string m_userData = this.m_userID.ToString()+","+this.m_loginName+","+this.m_userType.ToString();
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1,
"WebbUser",
System.DateTime.Now,
System.DateTime.Now.AddDays(30),
i_autoLogin,
m_userData,
"/");
string encTicket = FormsAuthentication.Encrypt(ticket);
HttpContext.Current.Response.Cookies.Add(new HttpCookie("WebbUser", encTicket));
}
其中m_userData可以是很長的字串,而且生成的cookies經過了加密(簡單的)。顯然,這裡只是會記錄一些使用者ID,TYPE等資訊,不會記錄密碼等重要資訊,當然也不會有什麼太大的問題。接下來就是如何取得cookies裡的資訊並且加以認證。
取回cookies:
protected void GetDataFromCookie()
{
if(User.Identity.IsAuthenticated)
{
string m_userData;
FormsIdentity id = (FormsIdentity)User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
m_userData = ticket.UserData;
if(m_userData!=null)
{
SetUserData(m_userData);
}
}
}
private void SetUserData(string m_Data)
{
string[] m_string = m_Data.Split(new char[]{','});
if(m_string.Length==3)
{
this.m_user.UserID = Convert.ToInt64(m_string[0]);
this.m_user.LoninName = m_string[1];
this.m_user.UserType = PageHelper.ConvertToUserTypes(m_string[2]);
}
}
顯然這裡我用了‘,’來分隔使用者資訊,其中我添加了三條使用者資訊,一條為使用者ID,一條為使用者名稱,最後一條為使用者型別。而且在取回資訊的時候,用它來給m_user物件賦值。
下面就是來驗證它了:首先寫一個基類(BasePage),以後所有的Form都從它派生,這樣就可以自動驗證使用者了。它裡面寫一個可過載函式,用於對不同的頁面進行判斷:
#region IUIPage Members
virtual public bool CheckUserType(){return false;}
virtual public void InitUser(object sender, EventArgs e){}
#endregion
而且在頁面載入的時候進行驗證:
public void BasePage_Load(object sender, System.EventArgs e)
{
if(!CheckUserType())
{
this.UserSignOut();
}
}
而實現的驗證程式碼在不同的頁面裡:例如一個Admin_Main.aspx.cs裡,它的驗證可能是這樣的:
public override bool CheckUserType()
{
return this.m_user.UserType==UserTypes.Admin?true:false;
}
public override void InitUser(object sender, EventArgs e)
{
this.m_user = new WebbAdmin2() as IVisitor;
this.GetDataFromCookie();
}
而在Client_Main.aspx.cs裡可能是這樣的:
public override bool CheckUserType()
{
return this.m_user.UserType==UserTypes.Client?true:false;
}
public override void InitUser(object sender, EventArgs e)
{
this.m_user = new WebbClient() as IVisitor;
this.GetDataFromCookie();
}