使用HttpContext的User屬性來實現用戶驗證

轉自:http://blog.csdn.net/yan0lovesha/archive/2005/01/13/252508.aspx
HttpContext
類包含了個別HTTP請求的所有特定HTTP信息。這個示例主要是講如何使用HttpContext類中的User屬性來實現用戶驗證!

用戶驗證是大部分ASP.NET WEB應用程序都要用到的,它在整個應用程序中佔有很重要的地位,在.NET中,包含了很多種用戶驗證方式,如衆所周知的PassPort認證,Windows認證,Form認證等等,可是這些都很難滿足我們在實際應用中的需求,以致於很多朋友都是自己另外寫代碼來實現自己需要的功能,這讓我們在安全性以及系統效率上要考慮很多。

實際上,ASP.NET中內置的用戶驗證機制功能非常強大,同時也具有非常好的的可擴展性,它能夠在HttpContext對象中生成一個名爲User的屬性,這個屬性能讓我們訪問各種信息,包括用戶是否已驗證,用戶的類型,用戶名等等,我們還可以對該屬性的功能進性擴展,以實現我們的要求。

分配給HttpContext.User的對象必須實現IPrincipal接口,而Iprincipal定義的屬性之一是Identity,它必須實現Iidentity接口。因爲,我們只要寫了實現這兩個接口的類,就可以在這些類中添加任何我們所需要的功能。

首先,我們創建兩個實現IprincipalIidentity的類,分另爲MyIprincipalMyIdentity

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

MyIprincipal.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,string password)

              {

                     //

                     // TODO: 在此處添加構造函數邏輯

                     //

                     identity = new MyIdentity(userID,password);

                     if(identity.IsAuthenticated)

                     {

                            //如果通過驗證則獲取該用戶的Role,這裏可以修改爲從數據庫中

                            //讀取指定用戶的Role並將其添加到Role中,本例中直接爲用戶添加一個Admin角色

                            roleList = new ArrayList();

                            roleList.Add("Admin");

                     }

                     else

                     {

                            // do nothing

                     }

              }

 

              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,string currentPassword)

              {

                     //

                     // TODO: 在此處添加構造函數邏輯

                     //

                     userID = currentUserID;

                     password = currentPassword;

              }

 

              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 CanPass();

                     }

              }

 

              public string Name

              {

                     get

                     {

                            // TODO:  添加 MyIdentity.Name getter 實現

                            return userID;

                     }

              }

 

              //這個屬性我們可以根據自己的需要來靈活使用,在本例中沒有用到它

              public string AuthenticationType

              {

                     get

                     {

                            // TODO:  添加 MyIdentity.AuthenticationType getter 實現

                            return null;

                     }

              }

 

              #endregion

       }

}

 

在完成了這兩個類之後我們還要創建一個自己的Page,來配合我們的驗證,這裏我們將其命名爲MyPage,繼承自Page

 

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.Cache["UserMessage"] != null)

                            {

                                   Hashtable userMessage = (Hashtable)Context.Cache["UserMessage"];

                                   MyPrincipal principal = new MyPrincipal(userMessage["UserID"].ToString(),userMessage["UserPassword"].ToString());

                                   Context.User = principal;

                            }

                     }

              }

       }

}

 

下面就是我們的界面WebForm.aspxWebForm.aspx.cs

 

WebForm.aspx

 

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="HttpContextUserEG.WebForm1" %>

<!DOCTYPE HTML PUBLIC "-//W<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />3C//DTD HTML 4.0 Transitional//EN" >

<HTML>

       <HEAD>

              <title>WebForm1</title>

              <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">

              <meta content="C#" name="CODE_LANGUAGE">

              <meta content="JavaScript" name="vs_defaultClientScript">

              <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">

       </HEAD>

       <body>

              <form id="Form1" method="post" runat="server">

                     <P><FONT face="宋體">用戶名:

                                   <asp:TextBox id="tbxUserID" runat="server"></asp:TextBox><BR>

                                   :

                                   <asp:TextBox id="tbxPassword" runat="server" TextMode="Password"></asp:TextBox></FONT></P>

                     <P><FONT face="宋體">

                                   <asp:Button id="btnLogin" runat="server" Text="登錄"></asp:Button>

                                   <asp:Label id="lblLoginMessage" runat="server"></asp:Label></FONT></P>

                     <P><FONT face="宋體">

                                   <asp:Panel id="Panel1" runat="server" Visible="False">

                                          <P>

                                                 <asp:Button id="btnAdmin" runat="server" Text="角色1"></asp:Button>

                                                 <asp:Button id="btnUser" runat="server" Text="角色2"></asp:Button></P>

                                          <P>

                                                 <asp:Label id="lblRoleMessage" runat="server"></asp:Label></P>

                                   </asp:Panel>

                                   <P></P>

                            </FONT>

              </form>

       </body>

</HTML>

 

WebForm1.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 = new MyPrincipal(tbxUserID.Text,tbxPassword.Text);

                     if(!principal.Identity.IsAuthenticated)

                     {

                            lblLoginMessage.Text = "用戶名或密碼不正確";

                            Panel1.Visible = false;

                     }

                     else

                     {

                            // 如果用戶通過驗證,則將用戶信息保存在緩存中,以備後用

                            // 在實際中,朋友們可以嘗試使用用戶驗證票的方式來保存用戶信息,這也是.NET內置的用戶處理機制

                            Context.User = principal;

                            Hashtable userMessage = new Hashtable();

                            userMessage.Add("UserID",tbxUserID.Text);

                            userMessage.Add("UserPassword",tbxPassword.Text);

                            Context.Cache.Insert("UserMessage",userMessage);

                            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";

                     }

              }

       }

}

 

代碼部分介紹完了,朋友們可以自己試試來看到效果,在這個例子中很多地方都爲了方便而直接給予賦值,在實際應用中,這些將是從數據庫或從其它配置文件中得到,而這種方法的可擴展性是非常高的,我們可以根據自己的需要來擴展MyIprincipalMyIdentity類的功能。比如我們可以添加一個IsInPermission來使用戶不僅屬於角色,每個角色還可以擁有不同的權限。在本例中,在用戶驗證過後是通過使用緩存來保存已驗證用戶的信息的,我們還可以嘗試使用用戶驗證票的方式來實現。

我們可以看到,這種用戶驗證機制,在我們的程序越寵大,它所帶來的好處就越多,而且他還有很多值得我們發掘的地方!

希望大家能和我互相交流!謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章