• ASP.NET安全问题Forms验证


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

           前言:在ASP.NET中,常用的就是Forms验证,最重要的原因就是灵活。因为Forms验证细细的谈起来也确实不少,而且我也不想草草的说完了事,那对大家和自己都不负责任的。

    系列文章链接:

    ASP.NET开发安全问题

    ASP.NET安全问题-- 创建安全的Web应用程序

    ASP.NET安全问题--ASP.NET安全架构

    ASP.NET安全问题--ASP.NET安全架构--如何实现.NET安全

    ASP.NET安全问题--ASP.NET生命周期中的验证以及身份验证模块

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

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

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

    ASP.NET安全问题--ASP.NET中的授权问题(前篇)

           本篇的话题如下:
      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 中的一个配置的节点:
    <authentication mode="Forms">
            <forms>
              <credentials>
                <user name="xiaoyang" password="xiaoyang"/>
                <user name="panyan" password="panyan"/>
              </credentials>
            </forms>
         </authentication>

           如果我们在配置文件配置了上述的信息,那么我们就可以用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中。

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

    引用:http://www.cnblogs.com/yanyangtian/archive/2009/05/24/1488344.html

  • 相关阅读:
    无尽的冒险
    推荐一款好用的markdown编辑器,还可以引入vue主题
    你是微光
    Echarts 空心饼图示例
    vue + element-ui 制作tab切换(切换vue组件,踩坑总结)
    vue + element-ui 制作tab切换(适用于单页切换不同标记显示不同内容)
    Element UI 封装Table --> 实现动态创建表头和单元格数据(单元格内可动态增加非纯文本的内容)
    Element UI 封装Table --> 实现动态创建表头和单元格数据(无需写死表头和单元格数据)
    vue 部署到生产出现语法错误和css警告(Resource interpreted as Stylesheet but transferred with MIME type text/html: "www.aaa.com/cal/static/css/app.c06.css". vendor.4b6.js:1 Uncaught SyntaxError: Unexpected token '<')
    使用vue-cookies插件操作cookie
  • 原文地址:https://www.cnblogs.com/chencidi/p/2117121.html
Copyright © 2020-2023  润新知