zoukankan      html  css  js  c++  java
  • Forms验证的过程

         +  Forms验证的过程
    来源:原创  日期:2004-9-21
     

    在web.config里做好设定,在ui层做好反应机制,接下来就可以把自己的web程序交给Forms验证来保护了,下面就来看Forms验证发挥作用的过程。
    首先,每当我们发送一个页面的请求,都会激发数个应用程序级(Application)的事件,其中和用户验证有关的是AuthenticateRequest,打开Global.asax.cs就可以看到它
    void Application_AuthenticateRequest(Object sender, EventArgs e)
    每次请求发送过来,都会进入这个处理方法里面,我们可以加入以下的代码,然后在第一句的位置设置断点,来查看一下他们的值,这样就会有清晰的认识啦
    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
       //获得请求发送者
       HttpApplication app=(HttpApplication)sender;
       // 检查是否通过验证
       if(app.Request.IsAuthenticated)
       {
          //在这里查看类型
          if(app.Context.User is System.Security.Principal.GenericPrincipal)
             if(app.Context.User.Identity.Name=="xx")
             {}
       }
    }

    从第一句那里就设断点,然后用f10步进查看各个的值,也可以把那些重要的添加到监视,比如app.Context.User和app.Context.User.Identity
    先说一下app.Context.User就相当于我们在ui层里使用的this.User。
    当请求第一次发过来的时候,也就是没有通过验证的时候,这个时候是没有调用FormsAuthentication.SetAuthCookie()的,注意看app.Context.User“未定义的值”,而app.Context.User.Identity根本不存在。
    然后进入login.aspx, 填好信息后,提交,检查信息,若有问题,则打回去,否则就调用FormsAuthentication.SetAuthCookie将用户凭证赋给当前用户
    通过验证后,再次进入该方法,这时监视窗口里的信息为:
    app.Context.User
    {System.Security.Principal.GenericPrincipal}
    System.Security.Principal.IPrincipal

    app.Context.User.Identity
    {System.Web.Security.FormsIdentity}
    System.Security.Principal.IIdentity

    很明显,在获得用户凭证后,app.Context.User是GenericPrincipal类型,而app.Context.User.Identity是FormsIdentity类型。
    GenericPrincipal的Identity返回一个实现IIdentity接口的对象,具体返回的值就看你在web.config里的设定,在这里当然就是返回FormsIdentity

    再接着往下想,一开始我们是用app.Request.IsAuthenticated检查,通过反射器查看的该方法的实现为:
    public bool IsAuthenticated
    {
       get
       {
          if ((this._context.User != null) && (this._context.User.Identity != null))
          {
             return this._context.User.Identity.IsAuthenticated;
          }
          return false;
       }
    }

    这就是为什么不直接用app.Context.User.Identity.IsAuthenticated的原因,因为它在里面替我们检查了app.Context.Use是否已经存在,而实际上,如果app.Context.User存在了,那肯定是通过验证了,即调用了FormsAuthentication.SetAuthCookie()方法,下面是其实现:
    public static void SetAuthCookie(string userName, bool createPersistentCookie)
    {
       FormsAuthentication.Initialize();
       FormsAuthentication.SetAuthCookie(userName, createPersistentCookie, FormsAuthentication.FormsCookiePath);
    }

    public static void SetAuthCookie(string userName, bool createPersistentCookie, string strCookiePath)
    {
       FormsAuthentication.Initialize();
       HttpContext.Current.Response.Cookies.Add(FormsAuthentication.GetAuthCookie(userName, createPersistentCookie, strCookiePath));
    }

    我们大多使用的是重载的第一个方法,它在里面调用了第二个方法,最关键的就是设定cookie那句啦,而不难想到,在Initialize()肯定是有对app.Context.User的初始化。

    汗……我发现我的表达能力越来越差了,再说下去恐怕自己都糊涂了,就在这里结尾吧。下面是我的总结:
    当用户没有通过验证时,一切都没有发生,根据web.config里各location的权限设定来加以保护,一旦用户填写完login.aspx的表单提交,并且通过验证,则调用FormsAuthentication.SetAuthCookie(),在这个方法里,设定了表示用户凭证的cookie,并且重新设定了Context的实例,以后就可以直接通过该Context的实例获得对实现IPrincipal接口的GenericPrincipal对象和实现IIdentity接口的FormsIdentity对象的访问。
    絮絮叨叨的写了这么多,不知大家明白了没有……其实认识这个过程,关键是为使用自己的验证体系做准备,当我们要自己实现IPrincipal和IIdentity来使用自定义的验证体系时,比如分别是REDPrincipal和REDIdentity,那就要考虑转换的问题,因为默认是转成了GenericPrincipalFormsIdentity。而转换的最佳地点就是在Application_AuthenticateRequest()方法里。
    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
       HttpApplication app=(HttpApplication)sender;
       if(app.Request.IsAuthenticated)
       {
          if(!(app.Context.User is Business.RedPrincipal))
          {
             app.Context.User=new Business.RedPrincipal(app.Context.User.Identity.Name);
          }
       }
    }



  • 相关阅读:
    菜鸡的Java笔记 第二十八
    菜鸡的Java笔记 第二十七
    菜鸡的Java笔记 第二十六
    菜鸡的Java笔记 第二十五 wrapperClass 包装类
    bzoj3238 [Ahoi2013]差异
    bzoj4516 [Sdoi2016]生成魔咒
    bzoj3998 [TJOI2015]弦论
    bzoj1965 [Ahoi2005]洗牌
    bzoj4896 [Thu Summer Camp2016]补退选
    bzoj5055 膜法师
  • 原文地址:https://www.cnblogs.com/wzyexf/p/396919.html
Copyright © 2011-2022 走看看