zoukankan      html  css  js  c++  java
  • 艾伟:ASP.NET安全问题--Forms验证的具体介绍(上篇) 狼人:

      本篇的话题如下:

      Forms验证的工作原理

      Forms验证中的API

      Forms验证的工作原理

      我们知道,Forms验证主要是基于cookie的,说白一点就是:把用户信息保存在cookie中,然后发送到客户端;再就是解析客户端的发送了的cookie信息,进行解析,然后进行验证。关于cookieless的工作原理和方法,我这里不赘述,大家可以参看我的另外的一片文章:浅谈ASP.NET内部机制(一)。

      当匿名用户请求一个需要验证后才能访问的资源和页面的时候,那么如果采用了Forms验证,那么URL授权模块就会把用户重定向到登录页面。而之前请求的URL就会被保存起来,等到用户正确的登录后,就再次转向之前要请求的页面。我想这点,大家应该都用过。

      下面我们就看看登录的时候发生了什么,看看登录的具体的流程?也请大家注意我使用的一些术语,因为这些术语再Forms中都有特定的对象,大家之后就可以看到的,很重要。

      1.再浏览器中有个登录窗体,要输入用户名和密码等凭证,通过提交给服务器的ASP.NET网站来审核,检查凭证是否正确。
      2.如果凭证正确,那么就会再服务器端就会创建一个"身份验证票据"。身份验证票据中含有了经过加密的用户信息。
      3.这个票据再服务器端被写入cookie中,然后发送到客户端。
      4.然后用户就被重定向到他们最初请求的URL中。


      注:大家可能会有疑问:最初请求的URL到底保存在哪里?不要担心,现在只要明白上面的流程就OK。
     
      5.上面第4步就是要转向最初请求的URL,假设最初的请求页面是Default.aspx,那么现在就是从登录的页面Login.aspx转向到Default.aspx 页面,此时因为身份验证的票据cookie已经存在于客户端的浏览器中了,此时的转向Default.aspx页面时,实际是再次向服务器端发起了请求,所以正如我们之前所谈到的:每个请求都要从ASP.NET管道中一级级的向后传,要经历ASP.NET的的生命周期:Application_BeginRequest,Application_AuthenticateRequest.....。(希望大家明白)

      但是这次的请求就和第一次我们发起的请求步同了,为什么?

      第一次我们请求Default.aspx页面的时候,我们根本就没有提供任何的表明我们身份的票据,但是这次我们已经登录了,而且我们的浏览器中已经有了我们的身份验证的票据的cookie,此时在Application_AuthenticateRequest事件中,Forms验证模块就获取表明我们身份cookie,然后就利用cookie中信息填充Context.User。

      验证模块处理完之后就是授权模块起作用了。其实URL授权模块就会利用我们之前填充在Context.User中的信息来验证用户是否被批准访问所请求的资源或者页面。
     
       Forms验证中的API

      实现Forms身份验证之前,我们看看组成Forms验证的API以及相关的类:
      FormsAuthenticationModule:对每个请求进行验证的HTTP模块
      FormsAuthentication:包含在Forms验证中我们常用的方法和属性(很重要的)
      FormsIdentity:Forms验证标识。
      FormsAuthenticationTicket:身份验证的票据,对用户的信息进行加密后的产物,我们一般把它写如cookie中,之前我们谈过了的。

      上面的类在System.Web.Security下。

      下面我们来一一介绍.

      FormsAuthenticationModule
      它是一个实现了IHttpModule接口的类。它可以用来处理每个请求的Application_AuthenticateRequest事件。如果发送了的请求中已经包含了cookie信息,那么这个模块就对cookie信息进行解密和解析,然后构造一个GenericPrincipal的类实例填充Context.User,并且也创建一个FormsIdentity的实例。
           注意:当我们在web.config中配置了Forms验证后,那么我们在Application_AuthenticateRequest事件写的代码要是和Forms相关的API。上篇文章谈过了。

      FormsAuthentication类 这个类很重要。

      还有一点注意的就是:因为FormsAuthentication和FormsAuthenticationModule名称很相似,很容易混淆。

      它们之前的区别在于,FormsAuthenticationModule是一个HTTP模块;而FormsAuthenticate是一个类,它有很多的方法和属性。更加直白的说就是:它们之前没有什么关联,只是在Application_AuthenticateRequest事件中我们常常要调用FormsAuthenticate类的一些方法和属性。而且FormsAuthenticate的很多方法都是静态的方法,我们不会创建FormsAuthenticate类的实例。

      还有一点要特别注意的就是FormsAuthenticate的Authenticate方法。
    我们之前说过了,我们一般是在登录窗体中提交用户信息,然后服务器端验证提交的信息,我们在服务器端常常是去数据库中检查这些信息的正确性,但是去数据库或者其他的数据存储(如文件,活动目录)中去检查只是一种情况。
    还有另外的情况。不知道大家是否记得web.config 中的一个配置的节点:

      如果我们在配置文件配置了上述的信息,那么我们就可以用Authenticate方法来检查提供了用户信息(用户名和密码)是否正确,如果我们没有在web.config配置用户的信息,也就是说我们是把信息保存在数据库等其他的地方,那么我们就不能Authenticate这个方法。当然我们很少用Authenticate这个方法,因为我们不可能把所有用户信息硬编码到配置文件中,但是还是要清楚这个方法。
     
      另外我简单的介绍一些常用的方法,具体的使用我以后会讲述。
    在FormsAuthenticate中使用频繁的是RedirectFromLoginPage方法。每当验证了用户的凭证后就会使用到这个方法,也就是我们之前说过的:跳转到我们最初请求的页面。
    这个方法就这么简单的一"跳",但是其实在内部做了很多的事情:
      1.为用户创建一个身份验证的票据
      2.对身份验证的票据进行加密
      3.创建一个cookie,把加密的票据保存在cookie中
      4.向HTTP响应添加cookie,并且发送给客户端。
      5.跳转,并且把用户重定向到最初请求的页面

      另外FormsAuthenticate类还有很多的其他方法和属性:
      FormsAuthenticate中涉及到客户端保存cookie的两个属性就是:
      FormsCookieName:获取或者设设置cookie的名称
      FormsCookiePath:获取或者设置cookie的url路径
      其中FormsCookiePath属性有一点要注意:大多数的浏览器会在判断cookie是否要和请求一起发送时,用到cookie路径。(我们一般在配置文件配置path="/"),如果我们配置的path不是"/",那么这个cookie就不会和请求发送到服务器端.
    FormsAuthenticate中和cookie操作相关的方法有:
      Decrypt:提取身份验证cookie的加密信息,创建FormsAuthenticationTicket,也就是解密。
      Encrypt:加密。从FormsAuthenticationTicket中获取信息,并且加密。以备我们之后把加密的信息写入cookie
      GetAuthCookie:创建身份验证cookie,但是并不把它立即添加到HTTP响应中
      SetAuthCookie:创建身份验证cookie,并且把它添加到Response.Cookie中。
      RenewTicketIfOld:刷新身份验证cookie的生命周期

      GetRedirectUrl:把用户重定向到他们最初请求的页面。
           SignOut:使得当前的身份验证cookie过期。我们常用的注销功能。
     
      FormsIdentity
      大家现在应该知道什么是标识 Identity,它包含了用户名和ID标识信息,可以参看我前面的文章。

      FormsAuthenticationTicket 票据
      通过上面的讲解,大家已经对它不陌生了,FormsAuthenticationTicket实际上就包含用户信息的一个类的实例。
    注意:FormsAuthenticationTicket和cookie之间的区别:
           cookie其实就是一个载体,容器,它包含了加密后的FormsAuthenticationTicket。

      FormsAuthenticationTicket类的UserName属性就是用户的用户名,我们可以根据这个属性识别不同的用户。
    由于身份验证是基于cookie的,所以要考虑到cookie的过期的问题。比如我们在登录时有个"记住我"的checkbox,如果勾上,那么就创建了一个永不过期的cookie,处于安全,我不提倡这样。

      所以在FormsAuthenticationTicket也提供了关于设置cookie属性:
      Expiration:获取一个表示cookie期满的DateTime对象
      Expired:判断cookie是否过期
      IsPersistent:是否在用户关闭浏览器后继续保存cookie
      IssueDate:返回最初设置cookie的时间

      还有就是CookiePath:设置cookie的保存路径,前面谈论过了,一般设置为"/"。
      另外FormsAuthenticationTicket身份验证票据目的是识别用户。同时,我们也可以利用FormsAuthenticationTicket的UserData属性添加额外的信息,如角色等,然后这额外的信息就可以保存在cookie中。

    今天就谈这里。大家先有个总体的认识,具体的代码部分,我们后面谈。谢谢各位!!!

  • 相关阅读:
    Sublime 下配置vim模式 + VintageEx-master下载地址
    Potplayer快捷键
    Failed to fetch URl https://dl-ssl.google.com/android/repository/addo Android SDK更新以及ADT更新出现问题的解决办法
    最快速的Android开发环境搭建ADT-Bundle及Hello World
    Android 开发环境下载地址 -- 百度网盘 adt-bundle android-studio sdk adt 下载
    X-Mirage苹果屏幕录制工具7天试用期破解 imsoft.cnblogs
    玩转博客园的心路总结
    玩转博客园的5个小技巧
    五个对你有用的Everything搜索技巧
    PS如何批量处理图片
  • 原文地址:https://www.cnblogs.com/waw/p/2156793.html
Copyright © 2011-2022 走看看