在 ASP.NET 中实现不同角色的用户使用不同登录界面的方法

很多用户在开发 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文件的主要内容:

  1. protected   void  Page_Load( object  sender, EventArgs e)  
  2. {  
  3. String ReturnUrl = Request.QueryString["ReturnUrl" ];  
  4. if  (ReturnUrl ==  null  || ReturnUrl.Equals(String.Empty))  
  5. {  
  6.   //默认情况下,按普通用户进行登录   
  7.   Response.Redirect("~/UserLogin.aspx" );  
  8. }  
  9. else   
  10. {  
  11.   if  (ReturnUrl.ToLower().Contains( "/admin/" ))  
  12.   {  
  13.     Response.Redirect("~/AdminLogin.aspx?ReturnUrl="  + Server.UrlEncode(ReturnUrl));  
  14.   }  
  15.   else   
  16.   {  
  17.     Response.Redirect("~/UserLogin.aspx?ReturnUrl="  + Server.UrlEncode(ReturnUrl));  
  18.   }  
  19. }  

protected 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这个文件的内容如下:

  1. <%@ Page Language= "C#"  %>  
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"   
  3.  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >  
  4. <mce:script runat="server" ><!--  
  5.   protected   void  Button1_Click( object  sender, EventArgs e)  
  6.   {  
  7.     //密码验证过程在此省略,假如用户名是mxh,密码是mengxianhui   
  8.     String UserName = "mxh" ;  
  9.     FormsAuthenticationTicket ticket = new  FormsAuthenticationTicket(2, //票证的版本号   
  10.         UserName,//与身分验证票关联的用户名   
  11.         DateTime.Now, //票证发出时的本地 日期和时间   
  12.         DateTime.Now.AddHours(1),//票证过期的本地日期和时间   
  13.         true , // 如果票证存储在持久性cookie中(跨浏览器会话保存)则为 true 否则为false 如果票证储存在 URL中,将忽略此值   
  14.         "reader" , //储存在 票证中持定的用户信息,本页面供 reader 登录使用   
  15.         FormsAuthentication.FormsCookiePath //票证储存在cookie中的路径   
  16.     );  
  17.     //如果 forms 元素的 protection 属性设置为 All 或 Encryption,则窗体身份验证 使用 Encrypt 方法对窗体身份验证票进行加密和签名。   
  18.     string  encTicket = FormsAuthentication.Encrypt(ticket);  
  19.     HttpCookie cookie = new  HttpCookie(FormsAuthentication.FormsCookieName, encTicket);  
  20.     Response.Cookies.Add(cookie);  
  21.     Response.Redirect(FormsAuthentication.GetRedirectUrl(UserName, true ));  
  22.   }  
  23. // --></mce:script>   
  24. <html xmlns="http://www.w3.org/1999/xhtml" >  
  25. <head runat="server" >  
  26.   <title>孟宪会之多用户登录测试页面</title>  
  27. </head>  
  28. <body>  
  29.   <form id="form1"  runat= "server" >  
  30.     普通用户登录界面省略<br />  
  31.   <asp:Button ID="Button1"  runat= "server"  OnClick= "Button1_Click"  Text= "普通用户登录"  />  
  32.   </form>  
  33. </body>  
  34. </html>  

<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <mce: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)); } // --></mce: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这个文件的全部内容如下:

  1. <%@ Page Language= "C#"  %>  
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"   
  3.  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >  
  4. <mce:script runat="server" ><!--  
  5.   protected   void  Button1_Click( object  sender, EventArgs e)  
  6.   {  
  7.     //密码验证过程在此省略,假如用户名是Admin,密码是mengxianhui   
  8.     FormsAuthenticationTicket ticket = new  FormsAuthenticationTicket(2, //票证的版本号   
  9.         "Admin" , //与身分验证票关联的用户名   
  10.         DateTime.Now, //票证发出时的本地日期和 时间   
  11.         DateTime.Now.AddHours(1),//票证过期的本地日期和时间   
  12.         true , // 如果票证存储在持久性cookie中(跨浏览器会话保存)则为 true 否则为false 如果票证储存在 URL中,将忽略此值   
  13.         "admin|manager|editor" , //储存在票证中持定的用户信息,本页面供 admin,manager,editor登录使用   
  14.         FormsAuthentication.FormsCookiePath //票证储存在cookie中的路径   
  15.     );  
  16.     //如果 forms 元素的 protection 属性设置为 All 或 Encryption,则窗体身份验证 使用 Encrypt 方法对窗体身份验证票进行加密和签名。   
  17.     string  encTicket = FormsAuthentication.Encrypt(ticket);  
  18.     HttpCookie cookie = new  HttpCookie(FormsAuthentication.FormsCookieName, encTicket);  
  19.     Response.Cookies.Add(cookie);  
  20.     Response.Redirect(FormsAuthentication.GetRedirectUrl("Admin"true ));  
  21.   }  
  22. // --></mce:script>   
  23. <html xmlns="http://www.w3.org/1999/xhtml" >  
  24. <head runat="server" >  
  25.   <title>孟宪会之多用户登录测试页面</title>  
  26. </head>  
  27. <body>  
  28.   <form id="form1"  runat= "server" >  
  29.   管理员登录界面,省略  
  30.   <asp:Button ID="Button1"  runat= "server"  Text= " 登  录 "  OnClick= "Button1_Click"  />  
  31.   </form>  
  32. </body>  
  33. </html>  

<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <mce: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)); } // --></mce: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 事件)里将角色信息附加到当前用户的上下文中。

  1. protected   void  Application_AuthenticateRequest( object  sender, EventArgs e)  
  2. {  
  3.   string  cookieName = FormsAuthentication.FormsCookieName;  
  4.   HttpCookie authCookie = Context.Request.Cookies[cookieName];  
  5.   if  ( null  == authCookie)  
  6.   {  
  7.     return ;  
  8.   }  
  9.   FormsAuthenticationTicket authTicket = null ;  
  10.   try   
  11.   {  
  12.     authTicket = FormsAuthentication.Decrypt(authCookie.Value);  
  13.   }  
  14.   catch  (Exception ex)  
  15.   {  
  16.     return ;  
  17.   }  
  18.   if  ( null  == authTicket)  
  19.   {  
  20.     return ;  
  21.   }  
  22.        
  23.   FormsIdentity id = new  FormsIdentity(authTicket);  
  24.   String[] roles = id.Ticket.UserData.Split('|' );  //读出在登录时设 置的角色列表。   
  25.   System.Security.Principal.GenericPrincipal principal = new  System.Security.Principal.GenericPrincipal(id, roles);  
  26.   Context.User = principal;//将验证信息 附加到当前用户上下文。   
  27. }  

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;//将验证信息附加到当前用户上下文。 }

4,在web.config文件中,允许登录文件的匿名访问,以便在未登录的情况下显示登录界面,注意:如果包含图片、css等文件,也需要设置这 些资源允许匿名访问。

  1. < configuration >   
  2.   < location   path = "AdminLogin.aspx" >   
  3.     < system.web >   
  4.       < authorization >   
  5.         < allow   users = "?" />   
  6.       </ authorization >   
  7.     </ system.web >   
  8.   </ location >   
  9.   < location   path = "UserLogin.aspx" >   
  10.     < system.web >   
  11.       < authorization >   
  12.         < allow   users = "?" />   
  13.       </ authorization >   
  14.     </ system.web >   
  15.   </ location >   
  16.     < system.web >   
  17.       < authentication   mode = "Forms" >   
  18.         < forms   loginUrl = "Login.aspx"   path = "/"   protection = "Encryption" > </ forms >   
  19.       </ authentication >   
  20.       < authorization >   
  21.         < deny   users = "?" />   
  22.         < allow   users = "*" />   
  23.       </ authorization >   
  24.     </ system.web >   
  25. </ configuration >   

<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/文件夹下的页面 中使用下面的方法得到当前登录的用户名和所具有的角色,根据角色来判断当前用户是否有权操作:

  1. Response.Write( "<li>当前登录用户 = "  + Page.User.Identity.Name);  
  2. Response.Write("<li>admin = "  + Page.User.IsInRole( "admin" ));  
  3. Response.Write("<li>reader = "  + Page.User.IsInRole( "reader" ));  

Response.Write("<li> 当前登录用户 = " + Page.User.Identity.Name); Response.Write("<li>admin = " + Page.User.IsInRole("admin")); Response.Write("<li>reader = " + Page.User.IsInRole("reader"));

为了简单起见,可以写一个Admin使用的基类页面,统一在基类页面中进行权限的处理。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值