登录设计步骤

 

参考

<script type="text/javascript">loadTOCNode(1, 'references');</script>
有关如何使用 <credentials> 部分存储用户和密码来实现基于窗体的简单身份验证的更多信息,请参阅以下 GotDotNet ASP.NET 快速入门示例:
基于窗体的身份验证
http://samples.gotdotnet.com/quickstart/aspplus/default.aspx?url=/quickstart/aspplus/doc/formsauth.aspx (http://samples.gotdotnet.com/quickstart/aspplus/default.aspx?url=/quickstart/aspplus/doc/formsauth.aspx)
有关如何使用 XML 文件存储用户和密码来实现基于窗体的身份验证的更多信息,请参阅 .NET Framework 软件开发工具包 (SDK) 文档中的以下主题:
使用 XML 用户文件的窗体身份验证
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconcookieauthenticationusinganxmlusersfile.asp (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconcookieauthenticationusinganxmlusersfile.asp)

  
  下面大概的看一下 Forms 的过程。
 Forms 身份验证基本原理:
  身份验证
    要采用 Forms 身份验证,先要在应用程序根目录中的 Web.config 中做相应的设置 :   
 <authentication mode="forms">
   <forms name=".ASPXAUTH " loginUrl="/login.aspx" timeout="30" path= "/">
   </forms>
 </authentication>
  
  其中 <authentication mode= "forms"> 表示本应用程序采用 Forms 验证方式。
 1. <forms> 标签中的 name 表示指定要用于身份验证的 HTTP Cookie 。默认情况下, name 的值是 .ASPXAUTH 。采用此种方式验证用户后 , 以此用户的信息建立一个 FormsAuthenticationTicket 类型的身份验证票 , 再加密序列化为一个字符串 , 最后将这个字符串写到客户端的 name 指定名字的 Cookie . 一旦这个 Cookie 写到客户端后 , 此用户再次访问这个 web 应用时会将连同 Cookie 一起发送到服务端 , 服务端将会知道此用户是已经验证过的 .
   再看一下身份验证票都包含哪些信息呢 , 我们看一下 FormsAuthenticationTicket :
 CookiePath 返回发出 Cookie 的路径。注意,窗体的路径设置为 / 。由于窗体区分大小写,这是为了防止站点中的 URL 的大小写不一致而采取的一种保护措施。这在刷新 Cookie 时使用
 Expiration 获取 Cookie 过期的日期 / 时间。
 IsPersistent 如果已发出持久的 Cookie ,则返回 true 。否则,身份验证 Cookie 将限制在浏览器生命周期范围内。
 IssueDate 获取最初发出 Cookie 的日期 / 时间。
 Name 获取与身份验证 Cookie 关联的用户名。
 UserData :获取存储在 Cookie 中的应用程序定义字符串。
 Version 返回字节版本号供将来使用。
  
  
  2. <forms> 标签中的 loginUrl 指定如果没有找到任何有效的身份验证 Cookie ,为登录将请求重定向到的 URL 。默认值为 default.aspx loginUrl 指定的页面就是用来验证用户身份的 , 一般此页面提供用户输入用户名和密码 , 用户提交后由程序来根据自己的需要来验证用户的合法性 ( 大多情况是将用户输入信息同数据库中的用户表进行比较 ), 如果验证用户有效 , 则生成同此用户对应的身份验证票 , 写到客户端的 Cookie, 最后将浏览器重定向到用户初试请求的页面 . 一般是用 FormsAuthentication.RedirectFromLoginPage 方法来完成生成身份验证票 , 写回客户端 , 浏览器重定向等一系列的动作 .
 public static void RedirectFromLoginPage( string userName, bool createPersistentCookie, string strCookiePath );
  其中 :
 userName 就是此用户的标示 , 用来标志此用户的唯一标示 , 不一定要映射到用户账户名称 .
 createPersistentCookie 标示是否发出持久的 Cookie
  若不是持久 Cookie Cookie 的有效期 Expiration 属性有当前时间加上 web.config timeout 的时间,每次请求页面时,在验证身份过程中,会判断是否过了有效期的一半,要是的话更新一次 cookie 的有效期;若是持久 cookie Expiration 属性无意义,这时身份验证票的有效期有 cookie Expires 决定, RedirectFromLoginPage 方法给 Expires 属性设定的是 50 年有效期。
 strCookiePath 标示将生成的 Cookie 的写到客户端的路径,身份验证票中保存这个路径是在刷新身份验证票 Cookie 时使用(这也是生成 Cookie Path ),若没有 strCookiePath 参数,则使用 web.config path 属性的设置。
  
  这里可以看到 , 此方法参数只有三个 , 而身份验证票的属性有七个 , 不足的四个参数是这么来的 :
 IssueDate Cookie 发出时间由当前时间得出 ,
 Expiration :过期时间由当前时间和下面要说的 <forms> 标签中 timeout 参数算出。此参数对非持久性 cookie 有意义。
 UserData 这个属性可以用应用程序写入一些用户定义的数据 , 此方法没有用到这个属性 , 只是简单的将此属性置为空字符串 , 请注意此属性 , 在后面我们将要使用到这个属性。
 Version 版本号由系统自动提供 .
  
 RedirectFromLoginPage 方法生成生成身份验证票后,会调用 FormsAuthentication.Encrypt 方法,将身份验证票加密为字符串,这个字符串将会是以 .ASPXAUTH 为名字的一个 Cookie 的值。这个 Cookie 的其它属性的生成: Domain Path 属性为确省值, Expires createPersistentCookie 参数而定,若是持久 cookie Expires 设为 50 年以后过期;若是非持久 cookie Expires 属性不设置。
  生成身份验证 Cookie 后,将此 Cookie 加入到 Response.Cookies 中,等待发送到客户端。
  最后 RedirectFromLoginPage 方法调用 FormsAuthentication.GetRedirectUrl 方法获取到用户原先请求的页面,重定向到这个页面。
  
 3. <forms> 标签中的 timeout path, 是提供了身份验证票写入到 Cookie 过期时间和默认路径。
  
  以上就是基于 Forms 身份验证的过程,它完成了对用户身份的确认。下面介绍基于 Forms 身份验证的访问授权。
  
  访问授权
   验证了身份,是要使用这个身份,根据不同的身份我们可以进行不同的操作,处理,最常见的就是对不同的身份进行不同的授权, Forms 验证就提供这样的功能。 Forms 授权是基于目录的,可以针对某个目录来设置访问权限,比如,这些用户可以访问这个目录,那些用户不能访问这个目录。
  同样,授权设置是在你要控制的那个目录下的 web.config 文件中来设置:
 <authorization>
   <allow users="comma-separated list of users"
   roles="comma-separated list of roles"
   verbs="comma-separated list of verbs" />
   <deny users="comma-separated list of users"
   roles="comma-separated list of roles"
   verbs="comma-separated list of verbs" />
 </authorization>
  
 <allow> 标签表示允许访问,其中的属性
 1. users :一个逗号分隔的用户名列表,这些用户名已被授予对资源的访问权限。问号 (?) 允许匿名用户;星号 (*) 允许所有用户。
 2. roles :一个逗号分隔的角色列表,这些角色已被授予对资源的访问权限。
 3. verbs :一个逗号分隔的 HTTP 传输方法列表,这些 HTTP 传输方法已被授予对资源的访问权限。注册到 ASP.NET 的谓词为 GET HEAD POST DEBUG
  
<deny> 标签表示不允许访问。其中的属性同上面的。
  
  在运行时,授权模块迭代通过 <allow> <deny> 标记,直到它找到适合特定用户的第一个访问规则。然后,它根据找到的第一项访问规则是 <allow> 还是 <deny> 规则来允许或拒绝对 URL 资源的访问。 Machine.config 文件中的默认身份验证规则是 <allow users="*"/> ,因此除非另行配置,否则在默认情况下会允许访问。
  
  那么这些 user roles 又是如何得到的呢?下面看一下授权的详细过程:
  
 1. 一旦一个用户访问这个网站,就行登录确认了身份,身份验证票的 cookie 也写到了客户端。之后,这个用户再次申请这个 web 的页面,身份验证票的 cookie 就会发送到服务端。在服务端, asp.net 为每一个 http 请求都分配一个 HttpApplication 对象来处理这个请求,在 HttpApplication.AuthenticateRequest 事件后,安全模块已建立用户标识,就是此用户的身份在 web 端已经建立起来,这个身份完全是由客户端发送回来的身份验证票的 cookie 建立的。
 2. 用户身份在 HttpContext.User 属性中,在页面中可以通过 Page.Context 来获取同这个页面相关的 HttpContext 对象。对于 Forms 验证, HttpContext.User 属性是一个 GenericPrincipal 类型的对象, GenericPrincipal 只有一个公开的属性 Identity ,有个私有的 m_role 属性,是 string[] 类型,存放此用户是属于哪些 role 的数组,还有一个公开的方法 IsInRole(string role) ,来判断此用户是否属于某个角色。
  由于身份验证票的 cookie 中根本没有提供 role 这个属性,就是说 Forms 身份验证票没有提供此用户的 role 信息,所以,对于 Forms 验证,在服务端得到的 GenericPrincipal 用户对象的 m_role 属性永远是空的。
 3. GenericPrincipal. Identity 属性是一个 FormsIdentity 类型的对象,这个对象有个 Name 属性,就是此用户的标示,访问授权就是将此属性做为 user 来进行授权验证的。 FormsIdentity 还有一个属性,就是 Ticket 属性,此属性是身份验证票 FormsAuthenticationTicket 类型,就是之前服务器写到客户端的身份验证票。
  服务器在获取到身份验证票 FormsAuthenticationTicket 对象后,查看这个身份验证票是不是非持久的身份验证,是的话要根据 web.config timeout 属性设置的有效期来更新这个身份验证票的 cookie (为避免危及性能,在经过了超过一半的指定时间后更新该 Cookie 。这可能导致精确性上的损失。持久性 Cookie 不超时。)
 4. HttpApplication.ResolveRequestCache 事件之前, asp.net 开始取得用户请求的页面,建立 HttpHandler 控制点。这就意味着,在 HttpApplication.ResolveRequestCache 事件要对用户访问权限就行验证,看此用户或角色是否有权限访问这个页面,之后在这个请求的生命周期内再改变此用户的身份或角色就没有意义了。
  
  以上是 Forms 验证的全过程,可以看出,这个 Forms 验证是基于用户的,没有为角色的验证提供直接支持。身份验证票 FormsAuthenticationTicket 中的 Name 属性是用户标示,其实还有一个属性 UserData ,这个属性可以由应用程序来写入自定义的一些数据,我们可以利用这个字段来存放 role 的信息,从而达到基于角色验证的目的。
  
Forms 身份验证基于角色的授权
  
  身份验证
   web.config <authentication> 的设置还是一样:    
   <authentication mode="forms">
   <forms name=".ASPXAUTH " loginUrl="/login.aspx" timeout="30" path= "/">
   </forms>
 </authentication>
  
 /login.aspx 验证用户合法性页面中,在验证了用户的合法性后,还要有个取得此用户属于哪些 role 的过程,这个看各个应用的本身如何设计的了,一般是在数据库中会有个 use_role 表,可以从数据库中获得此用户属于哪些 role ,在此不深究如何去获取用户对应的 role ,最后肯定能够获得的此用户对应的所有的 role 用逗号分割的一个字符串。
  在上面的非基于角色的方法中,我们用了 FormsAuthentication.RedirectFromLoginPage 方法来完成生成身份验证票 , 写回客户端 , 浏览器重定向等一系列的动作。这个方法会用一些确省的设置来完成一系列的动作,在基于角色的验证中我们不能用这一个方法来实现,要分步的做,以便将一些定制的设置加进来:
  
 1. 首先要根据用户标示,和用户属于的角色的字符串来创建身份验证票
 public FormsAuthenticationTicket(
 int version, // 设为 1
 string name, // 用户标示
 DateTime issueDate, //Cookie 的发出时间 , 设置为 DateTime.Now
 DateTime expiration, // 过期时间
 bool isPersistent, // 是否持久性 ( 根据需要设置 , 若是设置为持久性 , 在发出
 cookie ,cookie Expires 设置一定要设置 )
 string userData, // 这里用上面准备好的用逗号分割的 role 字符串
 string cookiePath // 设为 "/", 这要同发出 cookie 的路径一致 , 因为刷新 cookie
  要用这个路径
 );
  
 FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket (1,"kent",DateTime.Now, DateTime.Now.AddMinutes(30), false,UserRoles,"/") ;
  
 2. 生成身份验证票的 Cookie
 2.1 将身份验证票加密序列化成一个字符串
 string HashTicket = FormsAuthentication.Encrypt (Ticket) ;
 2.2 生成 cookie
 HttpCookie UserCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket) ;
 FormsAuthentication.FormsCookieName 是用来获取 web.config 中设置的身份验证 cookie 的名字 , 缺省为 " .ASPXAUTH".
  若身份验证票中的 isPersistent 属性设置为持久类 , 则这个 cookie Expires 属性一定要设置 , 这样这个 cookie 才会被做为持久 cookie 保存到客户端的 cookie 文件中 .
 3. 将身份验证票 Cookie 输出到客户端
  通过 Response.Cookies.Add(UserCookie) 将身份验证票 Cookie 附加到输出的 cookie 集合中 , 发送到客户端 .
 4. 重定向到用户申请的初试页面 .
  
  验证部分代码 ( 这部分代码是在 login.aspx 页面上点击了登录按钮事件处理代码 ):
  
 private void Buttonlogin_Click(object sender, System.EventArgs e)
 {
   string user = TextBoxUser.Text; // 读取用户名
   string password = TextBoxPassword.Text; // 读取密码
   if(Confirm(user,password) == true) //confirm 方法用来验证用户合法性的
   {
   string userRoles = UserToRole(user); // 调用 UserToRole 方法来获取 role 字符串
   FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket (1,user,DateTime.Now, DateTime.Now.AddMinutes(30), false,userRoles,"/") ; // 建立身份验证票对象
   string HashTicket = FormsAuthentication.Encrypt (Ticket) ; // 加密序列化验证票为字符串
   HttpCookie UserCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket) ;
 // 生成 Cookie
   Context.Response.Cookies.Add (UserCookie) ; // 输出 Cookie
   Context.Response.Redirect (Context.Request["ReturnUrl"]) ; // 重定向到用户申请的初始页面
  }
   else
   {
   // 用户身份未被确认时的代码
   }
 }
 // 此方法用来验证用户合法性的
 private bool Confirm(string user,string password)
 {
   // 相应的代码
 }
 // 此方法用来获得的用户对应的所有的 role 用逗号分割的一个字符串
 private string UserToRole(string user)
 {
   // 相应的代码
 }
  
  基于角色访问授权
  
  这里我们要做的是 , 将客户端保存的身份验证票中 UserData 中保存的表示角色的信息恢复到在服务端表示用户身份的 GenericPrincipal 对象中 ( 记住 , 原来的验证过程中 , GenericPrincipal 对象只包含了用户信息 , 没有包含 role 信息 )
  一个 Http 请求的过程中 ,HttpApplication.AuthenticateRequest 事件表示安全模块已建立用户标识,就是此用户的身份在 web 端已经建立起来 , 在这个事件之后我们就可以获取用户身份信息了 .
  HttpApplication.ResolveRequestCache 事件之前, asp.net 开始取得用户请求的页面,建立 HttpHandler 控制点 , 这时就已经要验证用户的权限了 , 所以恢复用户角色的工作只能在 HttpApplication.AuthenticateRequest 事件和 HttpApplication.ResolveRequestCache 事件之间的过程中做 .
  我们选择 Application_AuthorizeRequest 事件中做这个工作 , 可以在 global.asax 文件中处理 HttpApplication 的所有的事件 , 代码如下 :   
 protected void Application_AuthorizeRequest(object sender, System.EventArgs e)
 {
   HttpApplication App = (HttpApplication) sender;
   HttpContext Ctx = App.Context ; // 获取本次 Http 请求相关的 HttpContext 对象
   if (Ctx.Request.IsAuthenticated == true) // 验证过的用户才进行 role 的处理
   {
   FormsIdentity Id = (FormsIdentity)Ctx.User.Identity ;
   FormsAuthenticationTicket Ticket = Id.Ticket ; // 取得身份验证票
   string[] Roles = Ticket.UserData.Split (',') ; // 将身份验证票中的 role 数据转成字符串数组
   Ctx.User = new GenericPrincipal (Id, Roles) ; // 将原有的 Identity 加上角色信息新建一个 GenericPrincipal 表示当前用户 , 这样当前用户就拥有了 role 信息
   }
 }
   访问者同时具有了 user role 信息 , 就可以据此在 web.config 中用 role 来控制用户的访问权限了 .
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值