• 使用 forms 身份验证,避免重复造轮子


        最近开始一个小 asp.net 项目,整个项目需要登录才能操作。以前大家都采用 asp 的方式 session + cookie  来实现身份验证,我一直对 asp.net 自带的 forms 验证早就耳闻,苦于没实践,今天刚好逮到机会实际应用一下。
        问题:大家都说使用 forms 验证无法得到当前登录用户除了用户名之外的更多信息,经过我的一番小试验,在 forms 方式下自带的 userdata 可以为我们施展天地的地方。下面记录一下我的操作步骤备忘。

    step 1: web.config 配置关键地方:
    web.config配置
     1        <!--
     2            通过 <authentication> 节可以配置 ASP.NET 用来 
     3            识别进入用户的
     4            安全身份验证模式。 
     5        -->
     6    <authentication mode="Forms">
     7      <forms loginUrl="login.aspx" defaultUrl="index.aspx"
     8             name=".ztinfozero" path="/Manager" 
     9             slidingExpiration="true" timeout="10"></forms>
    10    </authentication>
    11    <authorization>
    12      <deny users="?"/>
    13    </authorization>
    14

        <!-- 实现自定义的 rolemanager 后需配置 :
        <roleManager defaultProvider="providerName(类名)"
            cookieName="role" cookiePath="/" enabled="true"
            cookieTimeout="30"  cookieSlidingExpiration="true"
            cookieRequireSSL="false" cookieProtection="All"
            cacheRolesInCookie="true">
          <providers>
            <clear />
            <add name="providerName(类名)" type="providerName(类名)" />
          </providers>
        </roleManager>
        -->


    step 2: 构造 SiteUser Model

    TopicUser Model
    [Serializable]
        
    public class TopicUser
        
    {
            
    public TopicUser() { }

            
    model 
        }


    step 3: 创建用户登录代码:

    数据库-用户登录方法


    step 4 : 创建登录页:

    代码
    protected void btnOK_Click(object sender, EventArgs e)
            
    {
                
    string username = tbname.Text.Trim();
                
    string pass = tbpass.Text.Trim();
                
    if (!string.IsNullOrEmpty(username)) {
                    
    if (!string.IsNullOrEmpty(pass)) {
                        DataService.User b 
    = new DataService.User();
                        DataService.TopicUser user 
    = b.UserLogon(username, pass);
                        
    if (user != null{
                            
    //roles , userid | userchname 
                            string userdata = string.Format("{0},{1}|{2}",
                                    user.UserPermit, user.autoID, user.UserChName);
                            
                            FormsAuthenticationTicket ticket 
    = new FormsAuthenticationTicket(
                                
    1, username, DateTime.Now, DateTime.Now.AddHours(2),
                                
    true, userdata);
                            
    string encticket = FormsAuthentication.Encrypt(ticket);
                            HttpCookie cookie 
    = new HttpCookie(
                                        FormsAuthentication.FormsCookieName, encticket);
                            Response.Cookies.Add(cookie);
                            Response.Redirect(
    "Index.aspx");
                        }


                    }

                }

            }


    step 5: 在 global.asax 里添加 Application_AuthenticateRequest 事件以设置当前登录用户的信息:

    Application_AuthenticateRequest
    /*****
    using System;
    using System.Security.Principal;
    using System.Web;
    using System.Web.Security;
    ****
    */


            
    protected void Application_AuthenticateRequest(object sender, EventArgs e)
            
    {
                HttpApplication app 
    = (HttpApplication)sender;
                HttpContext context 
    = app.Context;
                
    if (context.Request.IsAuthenticated) {
                    FormsIdentity id 
    = context.User.Identity as FormsIdentity;
                    FormsAuthenticationTicket ticket 
    = id.Ticket;
                    
    string[] roles = ticket.UserData.Split(',');
                    
    /* 
                     * 将原有的Identity加上角色信息新建一个GenericPrincipal表示当前用户
                     * 这样当前用户就拥有了role信息
                     * 据此在web.config中用role来控制用户的访问权限了. 
                     
    */

                    context.User 
    = new GenericPrincipal(id, roles);
                }

                
    old 
            }


    step 6: 如何得到当前登录用户的信息

    CurrentUser
            public static TopicUser CurrentUser {
                
    get {
                    DataService.TopicUser user 
    = new DataService.TopicUser();
                    FormsIdentity identity 
    = HttpContext.Current.User.Identity as FormsIdentity;
                    FormsAuthenticationTicket ticket 
    = identity.Ticket;
                    
    string userdata = ticket.UserData;  //获取自定义的 UserData 串 
                    
    if (!string.IsNullOrEmpty(userdata)) {
                        
    if (userdata.IndexOf(','> 0 && userdata.IndexOf('|'> 0)
                        
    {
                            
    //roles , userid | userchname 
                            string uinfo = userdata.Split(',')[1];
                            
    string[] u = uinfo.Split('|');
                            
    int uid = 0;
                            
    int.TryParse(u[0], out uid);
                            user.autoID 
    = uid;
                            user.UserChName 
    = u[1];
                            user.UserName 
    = HttpContext.Current.User.Identity.Name;
                        }

                    }

                    
    return user;
                }

            }

        由此得到当前登录用户的  ID 为 UserBase.CurrentUser.autoID ; 真实名字是: UserBase.CurrentUser.UserChName ;
    判断当前用户的角色是否为管理员: HttpContext.Current.User.IsInRole("1") ; // 1 为管理员

    退出当前登录的方法:

    LogOut.aspx
            protected void Page_Load(object sender, EventArgs e)
            
    {

                System.Web.Security.FormsAuthentication.SignOut();
                Response.Write(
    "<script>window.top.location='login.aspx';</script>");
                Response.End(); 
            }



        至此,身份验证完成。我们不用费尽心思在四处堆放用户是否登录判断的代码了。

  • 相关阅读:
    矩阵乘法优化求斐波那契
    高斯消元
    NOIP201305转圈游戏
    双六问题
    线段上格点的个数
    如何写出优雅的Python代码?
    sock.listen()
    python socket编程
    sc,sockname = sock.accept()
    格式化字符
  • 原文地址:https://www.cnblogs.com/infozero/p/1613631.html
Copyright © 2020-2023  润新知