艾伟: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中。

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

时间: 2024-09-30 10:11:50

艾伟:ASP.NET安全问题--Forms验证的具体介绍(上篇)的相关文章

ASP.NET安全问题--Forms验证的具体介绍(上篇)

前言:在ASP.NET中,常用的就是Forms验证,最重要的原因就是灵活.因为Forms验证细细的谈起来也确实不少,而且我也不想草草的说完了事,那对大家和自己都不负责任的. 本篇的话题如下: Forms验证的工作原理 Forms验证中的API Forms验证的工作原理 我们知道,Forms验证主要是基于cookie的,说白一点就是:把用户信息保存在cookie中,然后发送到客户端:再就是解析客户端的发送了的cookie信息,进行解析,然后进行验证.关于cookieless的工作原理和方法,我这里

asp.net 基于forms验证的目录角色权限的实现_实用技巧

但是我在使用过程中,发现针对角色的控制并不是那么容易,通过在网上查找资料,终于解决这个问题.下面将主要的注意事项列出来.1.配置文件中,角色的allow项要放在deny项的前面,users要配置为*,而不是? 代码 复制代码 代码如下: <location path="Doctors"> <system.web> <authorization> <allow roles="doctors"/> //这个在前 <d

ASP.NET 2.0验证cookie详解

对于ASP.NET Forms验证,想必大家都非常的熟悉.然而,在控制用户的(过期时间)expired time的时候,你是否遇到过一些奇怪的现象呢?虽说只是一个小小的cookie,但是其中可能有很多的东西你都不知道.今天我将和大家详细讨论一下cookie的注意点. 在ASP.NET 的Forms验证中,通常我们会使用ASP.NET自带的Login控件来进行验证.同时,在web.config文件中,我们所有的Forms设置都设为默认.现在,问题就来了. 1) 为什么我明明点了"Remember

艾伟:ASP.NET安全问题--Forms验证(后篇)--实战篇

       验证流程讲述        我们首先假设一个场景:用户现在已经打开了我们的首页Default.aspx,但是有些资源只能是登录用户才可以看到的,那么如果这个用户想要查看这些资源,那么他就要登录.而且这个用户已经有了一个帐号.(我们本篇主要的话题是身份验证,至于创建用户账户是怎么创建的,我们不关心,方法很多,如直接一个数据库插入就行了!)        我们现在就把我们的一些流程说下:       1.用户登录,在输入框中输入用户名和密码信息       2.点击登录按钮后,到数据库

艾伟_转载:ASP.NET Forms验证的安全性问题研究——为什么加密代码需要配置为服务

申明:这个帖子不是要你去干啥坏事,就是提醒一下你可能会遇到的安全性问题. ASP.Net提供了内置的登录验证,最为常用的就是Forms验证.讲解如何配置的文章非常多,这里就不再讲如何配置使用这个验证的方式了.下面讲讲其在安全性上存在的一些被忽视的问题.其实它本身没有问题,而使用的方式上会附带出来一些问题. 本文将分三部分讲实际应用中将会遇到的安全性问题,并且加以研究,并尝试提出解决方案. 一.简单的Forms被破解危机二.垂直划分站点的Forms被破解危机三.危机将带来什么后果    一.简单的

Asp.net中基于Forms验证的角色验证授权

asp.net Asp.net中基于Forms验证的角色验证授权 Asp.net的身份验证有有三种,分别是"Windows | Forms | Passport",其中又以Forms验证用的最多,也最灵活.Forms 验证方式对基于用户的验证授权提供了很好的支持,可以通过一个登录页面验证用户的身份,将此用户的身份发回到客户端的Cookie,之后此用户再访问这个web应用就会连同这个身份Cookie一起发送到服务端.服务端上的授权设置就可以根据不同目录对不同用户的访问授权进行控制了. 问

asp.net中使用基于角色的身份Forms验证,大致分为四个步骤

asp.net asp.net中使用基于角色的身份Forms验证,大致分为四个步骤1.配置系统文件web.config<system.web> <authentication mode="Forms" >  <forms name=".yaoCookies" loginUrl="/duan/Manage/login.aspx" protection="All"  timeout="20&

ASP.NET Forms验证实现子域名(SubDomain)共享登陆下的缺陷

一.什么是单点登录 单点登录就是在多个web应用程序中,实现统一登录方式,一但登录了某web应 用程序,其它相关联的web应用程序都无需再次登录,一个地方退出,所有相关联的 web应用程序都退出. 二.通过利用ASP.NET Forms验证模式可以实现子域名(SubDomain)共享登陆下 的缺陷 要利用Asp.NET Form验证模式实现同一主域下不同子域名共享登陆状态需要进 行以下配置 配置Web.config 1.把Asp.net的认证模式改为Forms认证模式,domain 要等于你的应

ASP.NET安全问题--Froms验证的具体介绍(中篇)

前言:今天是端午节,大家节日快乐!别忘了过我们的传统节日!!!因为前一篇文章已经谈论了与Forms验证有关的一些理论的知识,所以本篇主要讲述Forms验证一般的使用方法,也给出一些代码.可能有些话题之前园子里有朋友谈论过,如果有重复,那么就权当是复习也行! 本篇的话题如下: 启用Forms身份验证 用户信息的存储 web.config配置的一些用法 Forms验证简单的功能介绍 Forms验证中的Cookie问题 启用Forms身份验证 相信大家对很清楚如何启用 Forms验证,但是这里我还是罗