轉自:http://blog.csdn.net/yan0lovesha/archive/2005/01/16/255395.aspx
在我的上一篇《使用HttpContext中的User屬性來實現用戶身份驗證》中已經講了怎樣來使用HttpContext.User屬性來實現用戶身份驗證,並且還寫了一個示例程序。但是,在上一篇文章中,我們使用的是系統緩存來保存用戶的登錄信息,這無疑是佔用系統資源的一種做法,那有沒有更好的辦法呢?我在上一章中說過大家可以嘗試使用用戶驗證票的方式來保存用戶登錄信息的,這種方式是基於Cookie原理來實現的,因此避免了使用緩存所帶來的困擾。我們已經有了上一篇的基礎,這次只需要在它的基礎上稍加修改就可以了。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
要使用這種方法,我們首先要配置web.config文件,把<authentication>節點的屬性mode改爲Forms,再在該節點中添加<forms name="ContextUser" loginUrl="~/WebForm1.aspx" protection="None" slidingExpiration="true" />,這些代表的意思可以在MSDN上查到,這裏就不多作解釋了。
下面是修改後的代碼:
MyPage.cs
using System;
using System.Collections;
namespace HttpContextUserEG
{
/// <summary>
/// MyPage 的摘要說明。
/// </summary>
/// 繼承自Page類
public class MyPage : System.Web.UI.Page
{
public MyPage()
{
//
// TODO: 在此處添加構造函數邏輯
//
}
protected override void OnInit(EventArgs e)
{
base.OnInit (e);
this.Load +=new EventHandler(MyPage_Load);
}
//在頁面加載的時候從緩存中提取用戶信息
private void MyPage_Load(object sender, System.EventArgs e)
{
if(Context.User.Identity.IsAuthenticated)
{
if(!(Context.User is MyPrincipal))
{
MyPrincipal principal = new MyPrincipal(Context.User.Identity.Name);
Context.User = principal;
}
}
}
}
}
MyPrincipal.cs
using System;
using System.Collections;
namespace HttpContextUserEG
{
/// <summary>
/// MyPrincipal 的摘要說明。
/// </summary>
/// 實現IPrincipal接口
public class MyPrincipal : System.Security.Principal.IPrincipal
{
private System.Security.Principal.IIdentity identity;
private ArrayList roleList;
public MyPrincipal(string userID)
{
//
// TODO: 在此處添加構造函數邏輯
//
identity = new MyIdentity(userID);
roleList = new ArrayList();
roleList.Add("Admin");
}
public static MyPrincipal ValidateLogin(string userID,string password)
{
if(userID == "yan0lovesha" && password == "iloveshasha")
{
return new MyPrincipal(userID);
}
else
return null;
}
public ArrayList RoleList
{
get
{
return roleList;
}
}
#region IPrincipal 成員
public System.Security.Principal.IIdentity Identity
{
get
{
// TODO: 添加 MyPrincipal.Identity getter 實現
return identity;
}
set
{
identity = value;
}
}
public bool IsInRole(string role)
{
// TODO: 添加 MyPrincipal.IsInRole 實現
return roleList.Contains(role);;
}
#endregion
}
}
MyIdentity.cs
using System;
namespace HttpContextUserEG
{
/// <summary>
/// MyIdentity 的摘要說明。
/// </summary>
/// 實現IIdentity接口
public class MyIdentity : System.Security.Principal.IIdentity
{
private string userID;
private string password;
public MyIdentity(string currentUserID)
{
//
// TODO: 在此處添加構造函數邏輯
//
userID = currentUserID;
password = "iloveshasha"; //這裏實際上是從數據庫中獲得的密碼
}
private bool CanPass()
{
//這裏朋友們可以根據自己的需要改爲從數據庫中驗證用戶名和密碼,
//這裏爲了方便我直接指定的字符串
if(userID == "yan0lovesha" && password == "iloveshasha")
{
return true;
}
else
{
return false;
}
}
public string Password
{
get
{
return password;
}
set
{
password = value;
}
}
#region IIdentity 成員
public bool IsAuthenticated
{
get
{
// TODO: 添加 MyIdentity.IsAuthenticated getter 實現
return true;
}
}
public string Name
{
get
{
// TODO: 添加 MyIdentity.Name getter 實現
return userID;
}
}
//這個屬性我們可以根據自己的需要來靈活使用,在本例中沒有用到它
public string AuthenticationType
{
get
{
// TODO: 添加 MyIdentity.AuthenticationType getter 實現
return null;
}
}
#endregion
}
}
WebForm.aspx.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.Caching;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace HttpContextUserEG
{
/// <summary>
/// WebForm1 的摘要說明。
/// </summary>
/// 將這裏本來繼承自Page類改爲繼承自我們自己的MyPage類
public class WebForm1 : HttpContextUserEG.MyPage
{
protected System.Web.UI.WebControls.TextBox tbxUserID;
protected System.Web.UI.WebControls.TextBox tbxPassword;
protected System.Web.UI.WebControls.Panel Panel1;
protected System.Web.UI.WebControls.Button btnAdmin;
protected System.Web.UI.WebControls.Button btnUser;
protected System.Web.UI.WebControls.Label lblRoleMessage;
protected System.Web.UI.WebControls.Label lblLoginMessage;
protected System.Web.UI.WebControls.Button btnLogin;
private void Page_Load(object sender, System.EventArgs e)
{
// 在此處放置用戶代碼以初始化頁面
}
#region Web 窗體設計器生成的代碼
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 該調用是 ASP.NET Web 窗體設計器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// 設計器支持所需的方法 - 不要使用代碼編輯器修改
/// 此方法的內容。
/// </summary>
private void InitializeComponent()
{
this.btnLogin.Click += new System.EventHandler(this.btnLogin_Click);
this.btnAdmin.Click += new System.EventHandler(this.btnAdmin_Click);
this.btnUser.Click += new System.EventHandler(this.btnUser_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void btnLogin_Click(object sender, System.EventArgs e)
{
MyPrincipal principal = MyPrincipal.ValidateLogin(tbxUserID.Text,tbxPassword.Text);
if(principal == null)
{
lblLoginMessage.Text = "用戶名或密碼不正確";
Panel1.Visible = false;
}
else
{
// 如果用戶通過驗證,則生成用戶驗證票
Context.User = principal;
System.Web.Security.FormsAuthentication.SetAuthCookie(tbxUserID.Text,true);
lblLoginMessage.Text = tbxUserID.Text + "已經登錄";
Panel1.Visible = true;
}
}
private void btnAdmin_Click(object sender, System.EventArgs e)
{
// 驗證用戶的Role中是否包含Admin
if(Context.User.IsInRole("Admin"))
{
lblRoleMessage.Text = "用戶" + ((MyPrincipal)Context.User).Identity.Name + "屬於Admin組";
}
else
{
lblRoleMessage.Text = "用戶" + Context.User.Identity.Name + "不屬於Admin組";
}
}
private void btnUser_Click(object sender, System.EventArgs e)
{
// 驗證用戶的Role中是否包含User
if(Context.User.IsInRole("User"))
{
lblRoleMessage.Text = "用戶" + Context.User.Identity.Name + "屬於User組";
}
else
{
lblRoleMessage.Text = "用戶" + Context.User.Identity.Name + "不屬於User組";
}
}
}
}
WebForm.aspx不需要修改
大家可以對比這兩篇代碼的不同來理解這種用戶驗證機制!