在 ASP.NET 中實現不同角色的使用者使用不同登入介面的方法

孟子E章發表於2010-01-18

很多使用者在開發 ASP.NET 應用程式時都有這樣的需求:管理員角色的賬戶使用管理員的登入介面進行登入,普通使用者角色的賬戶使用普通使用者的登入介面進行登入。由於ASP.NET的 web.config裡只能使用一個 authentication mode="Forms" 節點,所以,要實現不同使用者採用不同的登入介面,一個辦法就是建立一個管理員專用的虛擬目錄,並設定為應用程式來實現。下面介紹另外一種採用重定向的辦法 來解決這個問題。

本文介紹的方法原理是根據登入介面的返回地址進行判斷,然後重定向到不同的頁面。下面就是實現的詳細過程。

1,建立一個網站,在網站裡建立Admin資料夾和User資料夾,分別存放admin和普通使用者所使用的檔案。也可以只設定一個 Admin 資料夾。由於本方法採用的判斷返回路徑的方法,所以,要能從路徑中區分出哪些是admin使用者使用的資料夾。當然,採用其他的判斷方法也是可以的。

2,在網站根目錄下分別建立3個登入檔案:Login.aspx、UserLogin.aspx和AdminLogin.aspx。其中Login.aspx檔案起地址轉換的作用,
Login.aspx檔案的主要內容:

C# 程式碼
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --&gtprotected void Page_Load(object sender, EventArgs e)
{
  String ReturnUrl
= Request.QueryString["ReturnUrl"];
  
if (ReturnUrl == null || ReturnUrl.Equals(String.Empty))
  {
    
//預設情況下,按普通使用者進行登入
    Response.Redirect("~/UserLogin.aspx");
  }
  
else
  {
    
if (ReturnUrl.ToLower().Contains("/admin/"))
    {
      Response.Redirect(
"~/AdminLogin.aspx?ReturnUrl=" + Server.UrlEncode(ReturnUrl));
    }
    
else
    {
      Response.Redirect(
"~/UserLogin.aspx?ReturnUrl=" + Server.UrlEncode(ReturnUrl));
    }
  }
}
在這個檔案的程式碼中,如果ReturnUrl中含有"/admin/",就重定向到AdminLogin.aspx登入介面;否則,就重定向到 UserLogin.aspx 登入介面。

UserLogin.aspx這個檔案的內容如下:
ASPX 程式碼
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --&gt@ Page Language="C#" %>
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<script. runat="server">
  protected
void Button1_Click(object sender, EventArgs e)
  {
    
//密碼驗證過程在此省略,假如使用者名稱是mxh,密碼是mengxianhui
    String UserName = "mxh";
    FormsAuthenticationTicket ticket
= new FormsAuthenticationTicket(2,//票證的版本號
        UserName,//與身分驗證票關聯的使用者名稱
        DateTime.Now, //票證發出時的本地日期和時間
        DateTime.Now.AddHours(1),//票證過期的本地日期和時間
        true,// 如果票證儲存在永續性cookie中(跨瀏覽器會話儲存)則為 true 否則為false 如果票證儲存在URL中,將忽略此值
        "reader",//儲存在票證中持定的使用者資訊,本頁面供 reader 登入使用
        FormsAuthentication.FormsCookiePath //票證儲存在cookie中的路徑
    );
    
//如果 forms 元素的 protection 屬性設定為 All 或 Encryption,則窗體身份驗證使用 Encrypt 方法對窗體身份驗證票進行加密和簽名。
    string encTicket = FormsAuthentication.Encrypt(ticket);
    HttpCookie cookie
= new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
    Response.Cookies.Add(cookie);
    Response.Redirect(FormsAuthentication.GetRedirectUrl(UserName,
true));
  }
script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  
<title>孟憲會之多使用者登入測試頁面title>
head>
<body>
  
<form. id="form1" runat="server">
    普通使用者登入介面省略
<br />
  
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="普通使用者登入" />
  
form>
body>
html>
這個檔案將驗證資訊儲存後,返回最初的請求頁面。注意:這裡連線資料庫驗證使用者名稱和密碼的過程省略過去了。

AdminLogin.aspx這個檔案的全部內容如下:
ASPX 程式碼
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --&gt@ Page Language="C#" %>
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<script. runat="server">
  protected
void Button1_Click(object sender, EventArgs e)
  {
    
//密碼驗證過程在此省略,假如使用者名稱是Admin,密碼是mengxianhui
    FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2,//票證的版本號
        "Admin",//與身分驗證票關聯的使用者名稱
        DateTime.Now, //票證發出時的本地日期和時間
        DateTime.Now.AddHours(1),//票證過期的本地日期和時間
        true,// 如果票證儲存在永續性cookie中(跨瀏覽器會話儲存)則為 true 否則為false 如果票證儲存在URL中,將忽略此值
        "admin|manager|editor",//儲存在票證中持定的使用者資訊,本頁面供 admin,manager,editor登入使用
        FormsAuthentication.FormsCookiePath //票證儲存在cookie中的路徑
    );
    
//如果 forms 元素的 protection 屬性設定為 All 或 Encryption,則窗體身份驗證使用 Encrypt 方法對窗體身份驗證票進行加密和簽名。
    string encTicket = FormsAuthentication.Encrypt(ticket);
    HttpCookie cookie
= new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
    Response.Cookies.Add(cookie);
    Response.Redirect(FormsAuthentication.GetRedirectUrl(
"Admin", true));
  }
script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  
<title>孟憲會之多使用者登入測試頁面title>
head>
<body>
  
<form. id="form1" runat="server">
  管理員登入介面,省略
  
<asp:Button ID="Button1" runat="server" Text=" 登  錄 " OnClick="Button1_Click" />
  
form>
body>
html>
注意:這裡連線資料庫驗證使用者名稱和密碼的過程省略過去了。

3,在Global的AuthenticateRequest 事件(一定要注意:不是 AuthorizeRequest 事件)裡將角色資訊附加到當前使用者的上下文中。

C# 程式碼
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --&gt@ Application Language="C#" %>
<script. RunAt="server">
  
protected void Application_AuthenticateRequest(object sender, EventArgs e)
  {
    
string cookieName = FormsAuthentication.FormsCookieName;
    HttpCookie authCookie
= Context.Request.Cookies[cookieName];
    
if (null == authCookie)
    {
      
return;
    }
    FormsAuthenticationTicket authTicket
= null;
    
try
    {
      authTicket
= FormsAuthentication.Decrypt(authCookie.Value);
    }
    
catch (Exception ex)
    {
      
return;
    }
    
if (null == authTicket)
    {
      
return;
    }
      
    FormsIdentity id
= new FormsIdentity(authTicket);
    String[] roles
= id.Ticket.UserData.Split('|'); //讀出在登入時設定的角色列表。
    System.Security.Principal.GenericPrincipal principal = new System.Security.Principal.GenericPrincipal(id, roles);
    Context.User
= principal;//將驗證資訊附加到當前使用者上下文。
  }
script>

4,在web.config檔案中,允許登入檔案的匿名訪問,以便在未登入的情況下顯示登入介面,注意:如果包含圖片、css等檔案,也需要設定這些資源允許匿名訪問。

XML/XHTML 程式碼
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --&gt<configuration>
  
<location path="AdminLogin.aspx">
    
<system.web>
      
<authorization>
        
<allow users="?"/>
      
authorization>
    
system.web>
  
location>
  
<location path="UserLogin.aspx">
    
<system.web>
      
<authorization>
        
<allow users="?"/>
      
authorization>
    
system.web>
  
location>

    
<system.web>
      
<authentication mode="Forms">
        
<forms loginUrl="Login.aspx" path="/" protection="Encryption">forms>
      
authentication>
      
<authorization>
        
<deny users="?"/>
        
<allow users="*"/>
      
authorization>
    
system.web>
configuration>

5,這樣,當訪問admin資料夾下的內容時,會直接轉到AdminLogin.aspx介面。在登入之後,就可以在/Admin/資料夾下的頁面中使用下面的方法得到當前登入的使用者名稱和所具有的角色,根據角色來判斷當前使用者是否有權操作:
C# 程式碼
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --&gtResponse.Write("
  • 當前登入使用者 =
  • " + Page.User.Identity.Name);
    Response.Write(
    "
  • admin =
  • " + Page.User.IsInRole("admin"));
    Response.Write(
    "
  • reader =
  • " + Page.User.IsInRole("reader"));
    為了簡單起見,可以寫一個Admin使用的基類頁面,統一在基類頁面中進行許可權的處理。

    來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15723462/viewspace-625408/,如需轉載,請註明出處,否則將追究法律責任。

    相關文章