ASP.NET Forms验证详解

来源:互联网 发布:简单的c语言游戏代码 编辑:程序博客网 时间:2024/05/21 17:28

创建网站中,常常会使用到身份验证。asp.net中内置了几种身份验证的方式,如Windows、Froms、Passport等。这几种身份验证的方式各有不同。一般来说,网站的身份验证方式都会经过以下几个步骤:

    1、输入用户名和密码,单击确定按钮。

    2、在后台判断用户名和密码是否正确,如果错误返回提示;如果正确,进入可访问的页面。

 

    在ASP时代,通常都会在验证用户名和密码是否匹配之后,创建一个Session,然后在每个需要验证的页面中判断Session是否存在,如果存在,则显示页面内容;如果不存在,产生提示,并跳转到登录页面。

 

    但是,在asp.net时代,这个过程就给大大的减化了,不再需要在每个需要验证的页面中去校验Session,只需要进行如下几步,就可以完成身份验证过程。

 

    第一步:修改web.config文件。

    1、在<system.web>和</system.web>中找到<authentication>节,将其改为“<authentication mode="Forms" />”,其中Forms代表使用表单认证。

    2、<system.web>和</system.web>中添加“<authorization><deny users="?"/></authorization>”,其中“<deny users="?"/>”代表拒绝所有的匿名用户。

 

    第二步:创建login.aspx文件。

    在经过第一步之后,无论用户访问网站中的哪个文件,只要没有经过身份验证,asp.net会自动跳转到login.aspx网页上,并且在URL中使用ReturnUrl参数来传递用户当前访问的网页。

    假设用户没有经过身份验证就直接访问test.aspx文件,那么asp.net会自动跳转了login.aspx网页,此时浏览器窗口中的地址栏中的URL为:“login.aspx?ReturnUrl=%2ftest.aspx”,因此,可以在身份验证通过后,再将网页跳回到ReturnUrl参数指定的网页上去。

 

    第三步:在login.aspx文件中验证身份。

    身份验证方式比较简单,一般都是创建一个文本框和一个密码框,用户输入用户名和密码后,单击提交按钮,则去数据库中验证身份,详细过程就不写了,在此只要输入的用户名为1,密码为2就认为身份验证通过。

    身份验证完毕之后,使用FormsAuthentication.SetAuthCookie()为用户创建一个身份验证的票据,并将其添加到Cookie中。以后,再访问网站中的其他网页,就不需要使用进行身份验证了。单击提交按钮后的代码如下所示。

    

[c-sharp] view plaincopy
  1. protected void Button1_Click(object sender, EventArgs e)  
  2. {  
  3.     //身份验证方式,本例中用户名为1,密码为2  
  4.     if (TextBox1.Text == "1" && TextBox2.Text == "2")  
  5.     {  
  6.         /* 
  7.          * 为用户名创建一个身份验证票据,并将其添加到响应的Cookie中 
  8.          * SetAuthCookie的第一个参数为已验证的用户的名称。 
  9.          * SetAuthCookie的第二个参数为true时代表创建持久Cookie(跨浏览器会话保存的 Cookie),为false则关闭浏览器后要重新验证身份 
  10.          */  
  11.         FormsAuthentication.SetAuthCookie(TextBox1.Text, false);  
  12.     }  
  13.     //如果URL中没有传递ReturnUrl参数,则跳转到Default.aspx,否则跳转到ReturnUrl参数值指定的网页  
  14.     if (string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]))  
  15.     {  
  16.         Response.Redirect("Default.aspx");  
  17.     }  
  18.     else  
  19.     {  
  20.         Response.Redirect(Request.QueryString["ReturnUrl"].ToString());  
  21.     }  
  22. }  
  23. 在上一篇博文《asp.net中的窗体身份验证(最简单篇)》中的身份验证虽然很简单,但是有一个缺点,就是访问整个网站都必须要经过身份验证,而事实上,很多网站都不会这么要求的。

        比如一个新闻系统,通常只有在发布新闻的网页才需要身份验证,而用户浏览新闻是不需要身份验证的。对于这种情况,就要针对不同的网页来进行身份验证了。

        要实现这种功能,也只要将《asp.net中的窗体身份验证(最简单篇)》稍作修改,具体操作方式如下所示:

     

        第一步、创建一个子文件夹,将所有要验证的网页都放在这个文件夹中,设置该文件夹的名字为“admin”。

     

        第二步、修改web.config文件。

        1、在<system.web>和</system.web>中找到<authentication>节,将其改为“<authentication mode="Forms"><forms loginUrl="~/admin/AdminLogin.aspx"></forms></authentication>”,其中Forms代表使用表单认证;loginUrl用于指定登录页面URL,个人比较喜欢将登录页面也放在admin文件夹中,所以在此要指定登录页面URL,如果还是想使用根目录中的login.aspx页面作为登录页面,则可以省略<forms>节。

        2、在<system.web>和</system.web>中添加“<authorization><allow users="?"/></authorization>”,其中“<allow users="?"/>”代表允许所有的匿名用户。注意此处与《asp.net中的窗体身份验证(最简单篇)》的区别,在《asp.net中的窗体身份验证(最简单篇)》中,此处使用的是“<deny users="?"/>”,用于拒绝所有匿名用户。

     

        第三步、在需要身份验证的子文件夹中添加一个web.config文件,在本例中为在“admin”文件夹中添加该文件。

     

        第四步、修改需要身份验证的子文件夹中的web.config文件,在本例中为“admin”文件夹中的web.config文件。

        在<system.web>和</system.web>中,添加“<authorization><deny users="?"/></authorization>”,由于在根目录中的web.config文件中声明了允许所有匿名用户访问,所以在不能允许匿名用户访问的子文件夹中,必须要使用“<deny users="?"/>”来拒绝匿名用户访问。另外,在子文件夹中的web.config文件中可以没有<authentication>节。

     

        第五步、在“admin”子文件夹中创建AdminLogin.aspx文件。如果在第二步中没有使用<forms>节来指定用户登录页面,则在网站根目录下创建login.aspx文件。

     

        第六步、在AdminLogin.aspx文件(或login.aspx文件)中验证身份,如果身份验证通过,使用FormsAuthentication.SetAuthCookie()为用户创建一个身份验证的票据,并将其添加到Cookie中。以后,再访问网站中admin子目录下的其他网页,就不需要使用进行身份验证了。单击提交按钮后的代码与《asp.net中的窗体身份验证(最简单篇)》中的代码类似,在此就不再赘述了。

    在《asp.net中的窗体身份验证(最简单篇) 》中介绍了使用FormsAuthentication.SetAuthCookie()方法创建身份验证票据的方法,事实上,这是一个使用缺省的身份验证票据的方法。在asp.net中,Forms身份验证的方式是在用户登录时创建一个身份验证票,然后将这个身份验证票存放在Cookie中,以后整个网站都可以通过这个Cookie来判断用户是否已经登录。如果用户浏览器不支持Cookie,asp.net也可以将票证放在URL的查询字符串中进行传递,这个不是本文的 重点,也就不详细介绍了。

     

        那么当访问一个asp.net的网站时,asp.net究竟是怎么进行身份验证的呢?

        在asp.net中,将身份验证分成了两个部分,第一个部分是IIS的身份验证,在用户访问网站时,IIS首先就会对用户进行身份验证,这个身份验证的具体设置在IIS中,这也非本文的重点,在此也不再详细介绍了。只有IIS通过了用户的身份验证之后,才会进行第二个部分的身份验证,这个部分的身份验证则由asp.net来完成。

     

        asp.net的身份验证方式由web.config文件中的<authentication>节点的mode属性值设置,如果要使用Forms身份验证,mode属性值必须为Forms。

        设置完<authentication>节点的mode属性值之后,我们还可以在该节点下添加一个<forms>节点,用于说明Forms身份验证的具体选项。常用的<authentication>节点的设置方式如下所示:

    [c-sharp] view plaincopy
    1. <authentication mode="Forms">  
    2.  <forms   
    3.    loginUrl="AdminLogin.aspx"  
    4.    timeout="30"   
    5.    name=".ASPXAUTH"   
    6.    path="/"   
    7.    requireSSL="false"   
    8.    cookieless="UseDeviceProfile"   
    9.    defaultUrl="default.aspx"   
    10.    slidingExpiration="true"   
    11.    protection="All"   
    12.    enableCrossAppRedirects="false">  
    13.  </forms>  
    14. </authentication>   

        以上代码中,loginUrl为用户登录网页,如果省略,asp.net将使用网站根目录下的login.aspx为登录页面。timeout设置登录超时时间为30分钟。name为存储身份验证票据的Cookie名,默认值为“.ASPXAUTH” 。path为存储身份验证票据的Cookie的路径,默认值为“/”。requireSSL为存储身份验证票据的Cookie是否使用SSL加密传输,默认为false。cookieless为浏览器不支持Cookie时的存储身份验证票据的传递方式,默认值为“UseDeviceProfile”,即自动检测浏览器是否支持Cookie,如果浏览器支持Cookie则使用Cookie传递身份验证票据,如果浏览器不支持Cookie则使用URL传递身份验证票据。defaultUrl为登录后默认跳转的网页,默认值为“default.aspx”。slidingExpiration为是否以执行可变的会话生存期,默认值为true。protection为Cookie的加密类型,默认值为“All”,即对Cookie同时使用数据验证和加密方法,其中数据验证算法由<machineKey>节点中设置。enableCrossAppRedirects是否将通过身份验证的用户重新定向到其它Web应用程序的URL中,默认值为false。

     

        在以上代码中,<forms>节点中的protection属性值为All,说明要对Cookie同时使用数据验证和加密方法,而数据验证算法由<machineKey>节点中设置,这就意味着要在<system.web>节点下添加一个<machineKey>子节点。<machineKey>节点的作用是对密钥进行设置,如以下代码所示:

    [c-sharp] view plaincopy
    1. <machineKey validation="3DES"/>  

     

      <authentication>节点用于设置asp.net的身份验证方式,也就是要怎么去验证用户身份,但验证完用户身份之后,哪些用户可以访问资源,<authentication>节点就不能进行设置了,这个使用就 必须要使用到<authorization>节点,该节点可以设置应用程序的授权,只有授权的用户才能访问网站资源。

        <authorization>节点下面可以有两种子节点:<allow>和<deny>。其中<allow>节点用于说明允许对网站资源访问的规则。<deny>节点用于说明禁止对网站资源访问的规则。

        拒绝匿名用户访问的设置方式如下所示:

     

    [c-sharp] view plaincopy
    1. <authorization>  
    2.     <deny users="?"/>  
    3. </authorization>>  

     

         经过以上几个步骤,web.config文件的修改基本上就结束了,一个完整的web.config文件如下所示:

    [c-sharp] view plaincopy
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <configuration>  
    3.     <appSettings/>  
    4.     <connectionStrings/>  
    5.     <system.web>  
    6.       <compilation debug="true" />  
    7.             <authentication mode="Forms">  
    8.                 <forms   
    9.                      loginUrl="AdminLogin.aspx"  
    10.                      timeout="30"   
    11.                      name=".ASPXAUTH"   
    12.                      path="/"   
    13.                      requireSSL="false"   
    14.                      cookieless="UseDeviceProfile"   
    15.                      defaultUrl="default.aspx"   
    16.                      slidingExpiration="true"   
    17.                      protection="All"   
    18.                      enableCrossAppRedirects="false">  
    19.                 </forms>  
    20.             </authentication>  
    21.             <authorization>  
    22.                 <deny users="?"/>  
    23.             </authorization>  
    24.             <machineKey validation="3DES"/>  
    25.     </system.web>  
    26. </configuration>  

     

        至此为止,网站窗体身份验证方式就已经创建完毕,此时,无法访问网站中的哪个网页,都会自动跳转到AdminLogin.aspx页面,下一步可以编写AdminLogin.aspx网页代码了。

        本文中涉及到的web.confing文件中的节点的详细解释可以在《asp.net中的窗体身份验证(完整篇之附录:web.config中相应节点详解)》中查阅。

    在《asp.net中的窗体身份验证(完整篇之一:创建asp.net的窗体身份验证方式) 》中介绍了如何通过修改web.config文件来创建窗体身份验证。修改完web.config文件之后,网站就可以使用窗体身份验证方式来验证用户身份了。那么,整个身份验证的过程是怎么样的呢?

     

        前面说过,在asp.net中,身份验证过程分为两部分,一部分是IIS中的身份验证,只有通过了IIS中的身份验证之后,才行进行asp.net中的身份验证。一个完整的窗体身份验证流程如下所示:

    1. 首先,用户通过浏览器向服务器发送一个网页请求,假设用户要访问index.aspx网页, 那么浏览器就会将请求发送给IIS服务器。
    2. 假设在该服务器中将IIS设置成可以匿名访问,那么IIS服务器将会允许访问index.aspx网页。
    3. IIS服务器允许访问之后,将会进入asp.net身份验证。asp.net会去web.config文件中查看<authorization>节点下的<deny>节点中是否拒绝所有匿名用户。如果拒绝了所有匿名用户,服务器则会去查找一个身份验证的Cookie。
    4. 如果服务器查找不到该身份验证的Cookie,就会将网页跳转到登录页面。这个登录页面为<forms>节点中的loginUrl属性值,默认为网站根目录下的login.aspx。在跳转到到登录页面时,服务器会将当前访问的网页的地址,如index.aspx,作为ReturnUrl参数值附加到login.aspx的URL中。如下所示:
      login.aspx?ReturnUrl=%2findex.aspx
    5. 用户在登录页面输入用户名和密码(或别的登录信息),并将这些信息提交到服务器。
    6. 服务器接收到用户提交的信息之后,判断用户是否为合法用户(判断方式有很多种,但这不是本文的重点),如果用户为合法用户,则创建一个包含窗体身份验证票的Cookie。
    7. 在创建完包含窗体身份验证票的Cookie之后,可以使用代码将网页跳回登录前访问的页面,如index.aspx网页(这个时侯ReturnUrl参数就起作用了)。
    8. 在登录后访问其它网页时(如跳转后的index.aspx页面),服务器会检测包含窗体身份验证的Cookie,并对用户进行身份验证。身份验证成功后,服务器返回用户需要访问的网页。

        以上就是一个完整的asp.net窗体身份验证流程,下面将会介绍如何按着该流程来编写asp.net代码。

    在《asp.net中的窗体身份验证(完整篇之二:asp.net的窗体身份验证过程) 》中我们介绍了asp.net的窗体身份验证过程,按照这个流程,我们可以开始动手编写网页代码。根据《asp.net中的窗体身份验证(完整篇之一:创建asp.net的窗体身份验证方式) 》中的web.config代码,我们网站的登录页面为AdminLogin.aspx。在没有登录的情况下,如果访问Default.aspx网页,服务器会自动跳转到AdminLogin.aspx,如下图所示。

        从上图中可以看出,浏览器地址栏中,AdminLogin.aspx后有参数ReturnUrl,而ReturnUrl的值跳转之间访问的Default.aspx网页。

     

        在上图所示页面中,用户可以输入用户名和密码,然后单击登录按钮提交信息。在后台,服务器接收到用户提交的信息后,可以判断用户提交的用户和密码是否匹配,如果匹配,则认为身份验证通过。这个时候,进入了《asp.net中的窗体身份验证(完整篇之二:asp.net的窗体身份验证过程) 》中的第6步,也就是“创建一个包含窗体身份验证票的Cookie”。

     

        所谓“创建一个包含窗体身份验证票的Cookie”,事实上是分两步走,第一步是创建一个窗体身份验证票,第二步是将身份验证票放在Cookie中。不过呢,在asp.net中,可以简化这个过程。

        方式一:使用默认的身份验证票。这个时候单击登录按钮的代码如下所示:

     

    [c-sharp] view plaincopy
    1. protected void Button1_Click(object sender, EventArgs e)  
    2. {  
    3.     Label1.Text = "";  
    4.     //当用户名为1,密码为2时,身份验证通过  
    5.     if (TextBox1.Text == "1" && TextBox2.Text == "2")  
    6.     {  
    7.         //方式一:使用默认的身份验证票,并跳转到初始请求的页面或默认页面  
    8.         FormsAuthentication.RedirectFromLoginPage("yundao"false);  
    9.     }  
    10.     else  
    11.     {  
    12.         Label1.Text = "用户名为1,密码为2,请重新输入";  
    13.     }  
    14. }  

        在以上代码中,为了方便起见,只要用户输入的用户名为1,密码为2,则认为身份验证通过。身份验证之后,接下来的三个动作应该是:

    1. 创建身份验证票;
    2. 将身份验证票放在Cookie中;
    3. 跳转到登录前的网页或默认网页。

        在asp.net中,使用FormsAuthentication类来操作Forms身份验证,该类中有一个RedirectFromLoginPage()方法,该方法可以一次性完成以上三个步骤:

    1. 创建一个默认的身份验证票。
    2. 将该默认的身份验证票存放在默认的Cookie中。此时,用于存放身份验证票的Cookie名由web.config文件中的<forms>节点的name属性值决定,如果没有设置该属性,默认情况下,Cookie名为“.ASPXAUTH”。
    3. 跳转网页。跳转网页的地址由登录页面的URL中的ReturnUrl参数决定,如上图所示,登录后将跳转到default.aspx页面。如果登录页面的URL中没有ReturnUrl参数(也就是说,直接访问的登录页面),那么将会跳转到web.config文件中的<forms>节点的defaultUrl属性值所指定的页面,如果没有设置该属性,默认情况下为default.aspx页面。

        RedirectFromLoginPage()方法中第一个参数为经过身份验证的用户名,这个用户名可以与用户的登录名相同,也可以不相同。第二个参数为是否创建永久的Cookie。通常为了安全起见,都不会创建永久的Cookie,因此该参数值通常为false。但如果创建的非永久的Cookie,那么在关闭浏览器窗口之后,再进入网站,就需要重新进行身份验证,而创建永久的Cookie,只要身份验证过之后,无论再打开该网站中的什么网页,都不会要求再一次登录。

        本例源代码可以在http://www.aspxfans.com/myBlogFile/窗体身份验证:使用RedirectFromLoginPage方法验证身份.rar或http://download.csdn.net/source/1962420中下载。

     

        以上方式是最简单的窗体身份验证方式,因为使用的是默认的身份验证票,但以上代码有一个缺点,就是身份验证通过后,要么跳转到登录页面前的网页,要么跳转到默认网页。如果想停留在当前网页,RedirectFromLoginPage()方法就无能为力了,在这种情况下,可以使用FormsAuthentication类的SetAuthCookie()方法,该方法的作用只是创建一个默认的身份验证票并将其写入Cookie中,但不跳转网页。如果要跳转网页的话,可以判断ReturnUrl参数值是否为空,再决定是否跳转网页。如以下代码所示:

    [c-sharp] view plaincopy
    1. protected void Button1_Click(object sender, EventArgs e)  
    2. {  
    3.     Label1.Text = "";  
    4.     //当用户名为1,密码为2时,身份验证通过  
    5.     if (TextBox1.Text == "1" && TextBox2.Text == "2")  
    6.     {  
    7.         //方式二:使用默认的身份验证票,并写入Cookie  
    8.         FormsAuthentication.SetAuthCookie("yundao"false);  
    9.         //判断初始请求页是否为空  
    10.         if (string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]))  
    11.         {  
    12.             Label1.Text = "登录成功,请选择以下网页:";  
    13.         }  
    14.         else  
    15.         {  
    16.             Response.Redirect(Request.QueryString["ReturnUrl"].Trim());  
    17.         }  
    18.     }  
    19.     else  
    20.     {  
    21.         Label1.Text = "用户名为1,密码为2,请重新输入";  
    22.     }  
    23. }  

        从以上代码可以看出,SetAuthCookie()方法与RedirectFromLoginPage()方法相比,缺少了跳转的步骤。因此,可以更加灵活地掌握用户跳转的页面。SetAuthCookie()方法的第一个参数也是经过身份验证的用户名,第二个参数也是是否创建永久的Cookie

        本例的源代码可以在http://www.aspxfans.com/myBlogFile/窗体身份验证:使用SetAuthCookie方法验证身份.rar 或 http://download.csdn.net/source/1962893下载。

     

        事实上,FormsAuthentication类还有一个GetRedirectUrl()方法,该方法可以返回初始请求页或默认页面,使用该方法也可以跳转页面。如以下代码所示:

    [c-sharp] view plaincopy
    1. protected void Button1_Click(object sender, EventArgs e)  
    2. {  
    3.     Label1.Text = "";  
    4.     //当用户名为1,密码为2时,身份验证通过  
    5.     if (TextBox1.Text == "1" && TextBox2.Text == "2")  
    6.     {  
    7.         //方式三:使用默认的身份验证票,并写入Cookie  
    8.         FormsAuthentication.SetAuthCookie("yundao"false);  
    9.         //跳转到初始请求页或默认页面  
    10.         Response.Redirect(FormsAuthentication.GetRedirectUrl("yundao",false));  
    11.     }  
    12.     else  
    13.     {  
    14.         Label1.Text = "用户名为1,密码为2,请重新输入";  
    15.     }  
    16. }  

        GetRedirectUrl()方法的第一个参数为经过身份验证的用户名,但第二个参数是可以忽略的参数,通常设为false。以上代码与FormsAuthentication.RedirectFromLoginPage("yundao", false)是等价的。

        本例的源代码可以在http://www.aspxfans.com/myBlogFile/窗体身份验证:使用GetRedirectUrl方法跳转网页.rar 或 http://download.csdn.net/source/1962898下载。

     

        前面介绍了三种窗体身份验证的方法,这三种方法中都使用了默认的身份验证票,而默认的身份验证票中只能传递经过验证的用户名,而不能传递其他数据。如果一个网站中,对不同的身份的用户给予不同的权限,那么以上三种方法都不适用了。由于要传递其他数据,所以必须要使用自定义的身份验证票,如以下代码所示:

    [c-sharp] view plaincopy
    1. protected void Button1_Click(object sender, EventArgs e)  
    2. {  
    3.     Label1.Text = "";  
    4.     //当用户名为1,密码为2时,身份验证通过  
    5.     if (TextBox1.Text == "1" && TextBox2.Text == "2")  
    6.     {  
    7.         //方式四:创建自定义身份验证票  
    8.         FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "yundao", DateTime.Now, DateTime.Now.AddMinutes(30), false"admin");  
    9.         //将身份验证票加密  
    10.         string EncrTicket = FormsAuthentication.Encrypt(ticket);  
    11.         //创建一个Cookie  
    12.         HttpCookie myCookie = new HttpCookie(FormsAuthentication.FormsCookieName, EncrTicket);  
    13.         //将Cookie写入客户端  
    14.         Response.Cookies.Add(myCookie);  
    15.         //跳转到初始请求页或默认页面  
    16.         Response.Redirect(FormsAuthentication.GetRedirectUrl("yundao",false));  
    17.     }  
    18.     else  
    19.     {  
    20.         Label1.Text = "用户名为1,密码为2,请重新输入";  
    21.     }  
    22. }  

        在以上代码中,首先,使用new FormsAuthenticationTicket()语句创建了一个身份验证票,FormsAuthenticationTicket()的第一个参数为身份验证票的版本号,通常为1;第二个参数为经过验证的用户名;第三个参数为票证发出时的本地时间;第四个参数为票证过期时的本地时间;第五个参数为是否创建永久的Cookie;第六个参数,也就是最重要的参数,为要传递的用户数据。如果不需要传递用户数据,可以设为null。但本人建议使用空字符串,否则为票证加密时可能会产生意想不到的问题。

        创建完身份验证票之后,可以使用FormsAuthentication类的Encrypt()方法为身份验证票加密,加密后返回一个字符串。

        然后创建一个Cookie,FormsAuthentication.FormsCookieName属性可以返回存放身份验证票的Cookie名,也就是web.config中<Forms>小节的name属性值。当然,在这里还可以设置一些Cookie相关的属性,如Cookie的path、expires、domain等,这此就不多介绍了。

        最后,将Cookie写入到客户端。

        这样,一个完整的身份验证就完成了,最后还可以选择是否跳转页面。

        本例的源代码可以在http://www.aspxfans.com/myBlogFile/窗体身份验证:使用自定义的身份验证票.rar 或 http://download.csdn.net/source/1962904下载。本例的优点是可以传递用户数据,但在传递用户数据时,必须要注册,每个Cookie的大小不能超过4KB,所以传递用户的数据不能太大。

     

        以上四个例子在vs2005中测试通过。

     在《asp.net中的窗体身份验证(完整篇之三:用户登录页面) 》中介绍了如何创建一个自定义身份验证票,如何将自定义的身份验证票写入Cookie中。而在自定义的身份验证票中,可以传递一个用户数据,这个用户数据十分有用。可以用来存放用户权限等级、用户VIP号、用户角色等数据,而这些数据往往可以用来控制用户的权限范围。下面我们来看一下怎么样获得用户数据。

     

        首先,修改web.config文件,这个就不再多介绍了,不明白的朋友去查看《asp.net中的窗体身份验证(完整篇之一:创建asp.net的窗体身份验证方式) 》和《asp.net中的窗体身份验证(完整篇之附录:web.config中相应节点详解) 》

        其次,创建用户登录页面,在本例中为AdminLogin.aspx,在单击登录按钮后,代码如下所示:

    [c-sharp] view plaincopy
    1. protected void Button1_Click(object sender, EventArgs e)  
    2. {  
    3.     Label1.Text = "";  
    4.     //用户名  
    5.     string UserName = TextBox1.Text;  
    6.     //密码  
    7.     string UserPassword = TextBox2.Text;  
    8.     //用户角色  
    9.     string UserRole = "";  
    10.     //用户身份验证  
    11.     if ((UserName == "1" && UserPassword == "2") || (UserName == "3" && UserPassword == "4"))  
    12.     {  
    13.         //判断用户权限  
    14.         if (UserName == "1")  
    15.         {  
    16.             UserRole = "admin";  
    17.         }  
    18.         else  
    19.         {  
    20.             UserRole = "reader";  
    21.         }  
    22.         //创建一个身份验证票  
    23.         FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "yundao", DateTime.Now, DateTime.Now.AddMinutes(30), false, UserRole);  
    24.         //将身份验证票加密  
    25.         string EncrTicket = FormsAuthentication.Encrypt(ticket);  
    26.         //创建一个Cookie  
    27.         HttpCookie myCookie = new HttpCookie(FormsAuthentication.FormsCookieName, EncrTicket);  
    28.         //将Cookie写入客户端  
    29.         Response.Cookies.Add(myCookie);  
    30.         //跳转到初始请求页或默认页面  
    31.         Response.Redirect(FormsAuthentication.GetRedirectUrl("yundao",false));  
    32.     }  
    33.     else  
    34.     {  
    35.         Label1.Text = "用户名为1,密码为2,或用户名为3,密码为4。请重新输入。";  
    36.     }  
    37. }  

        在本例中,为了简单起见,只要用户名为1、密码为2,或用户名为3、密码为4,都认为身份验证通过。身份验证通过后,创建一个身份验证票,如果用户名为1,身份验证票中传递的用户数据为“admin”,如果用户名为3,身份验证中传递的用户数据为“reader”。然后加密身份验证票,写入客户端Cookie。

        第三,创建一个test.aspx文件,在该文件中获得用户数据,如以下代码所示。

    [c-sharp] view plaincopy
    1. protected void Page_Load(object sender, EventArgs e)  
    2. {  
    3.     //获得存放身份验证票的Cookie值,这个值是经过加密的  
    4.     string EncrTicket = Request.Cookies[FormsAuthentication.FormsCookieName].Value;  
    5.     //获得身份验证票  
    6.     FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(EncrTicket);  
    7.     //从身份验证票中提取经过验证的用户名  
    8.     string UserName = ticket.Name;  
    9.     //从身份验证票中提取用户数据  
    10.     string UserData = ticket.UserData;  
    11.     Label1.Text = UserName + ",您好!您的权限为:" + UserData;  
    12. }  

        在以上代码中,先使用Request.Cookies获得存放身份验证票的Cookie,其中Cookie名可以通过FormsAuthentication类的FormsCookieName属性获得。

        由于身份验证票是加密后存放在Cookie中的,所以在获得Cookie值之后,必须将身份验证票解密。FormsAuthentication类的Decrypt()方法可以将加密后的身份验证票(也就是存放在Cookie中的字符串)解密,并返回解密后的身份验证票。在asp.net中使用FormsAuthenticationTicket类来代表身份验证票。

        获得解密后的身份验证票后,可以通过FormsAuthenticationTicket类的Name属性返回经过验证的用户名,也可以通过UserData属性获得用户数据。

    前面介绍过了如何使用Forms方式进行用户身份验证,然而,在大多网站中都会有一个“退出”功能,让用户可以通出登录。在asp.net中,退出的方式很简单,只要在退出页面中加上代码“FormsAuthentication.SignOut()”即可。

        你可以使用Response.Redirect()在退出之后将网页跳转到另一个网页,也可以使用“FormsAuthentication.RedirectToLoginPage()”将网页跳转到登录页面。

    在《asp.net中的窗体身份验证(最简单篇)》说明了如何让通过了身份验证的用户访问网站,但是该方法中有一个缺点,就是访问整个网站都需要用户身份验证。因此,在《asp.net中的窗体身份验证(分目录验证篇)》中介绍了如何让通过了身份验证的用户访问特定的目录,例如网站根目录中的网页是任何用户都能访问的,而admin目录则只能让通过身份验证的用户访问。这种方法可以解决大部分网站的身份控制,但是,对于一 些复杂的网站而言, 这种方式就有点捉袊见肘了。例如,有一个网站,我们要求根目录中的网页可以让任何用户浏览,而admin目录中的网页只有管理员才能访问、backup目录中的网页只有管理员和系统备份员才能访问、user目录中的网页除了匿名用户之外的所有用户都能访问,对于这种情况,那要怎么办呢?是不是还可以使用Forms身份验证呢?

        答案是肯定的,使用Forms身份验证可以通过角色的方式来达到上述目的。在本例中,我们可以先设定三种角色:admin、backup和reader,其中,admin角色也就是管理员角色,该角色可以访问admin目录、backup目录和user目录;backup角色也就是系统备份员角色,该角色不能访问admin目录,但可以访问backup目录和user目录;而reader角色是普通用户角色,该 角色不能访问admin目录、backup目录,只能访问user目录。

     

        第一步、设置Forms身份验证方式和登录网页。

        要达到上述目的,首先我们需要修改web.config文件,这次修改的目的是让网站拥有Forms身份验证功能(详见《asp.net中的窗体身份验证(最简单篇)》、《asp.net中的窗体身份验证(分目录验证篇)》和《asp.net中的窗体身份验证(完整篇之附录:web.config中相应节点详解)》),修改方式是:在<system.web>和</system.web>中找到<authentication>节,将其改为“<authentication mode="Forms"></authentication>”,其中Forms代表使用表单认证。

        当然,你也可以在web.config文件中设置用户登录的网页,设置方法为:在<authentication mode="Forms">和</authentication>节点中添加“<forms loginUrl="~/login.aspx"></forms>”代码,其中loginUrl参数用于说明录页面,如果没有设置该参数的话,默认的登录网页就是网站根目录的login.aspx网页。完整的代码如下所示:

    [c-sharp] view plaincopy
    1. <authentication mode="Forms"><!--验证方式为窗体验证-->  
    2.     <forms loginUrl="~/login.aspx"></forms><!--登录网页为login.aspx-->  
    3. </authentication>  
     

     

        第二步、设置默认的用户访问方式。

        在本例中,我们要求是网站根目录中的网页可以让匿名用户访问,因此,在设置完Forms身份验证方式之后,我们还要设置默认的用户访问方式——也就是让所有的匿名用户访问。设置方式是:在<system.web>和</system.web>节点中添加以下代码:

    [c-sharp] view plaincopy
    1. <authorization>  
    2.     <allow users="?"/><!--默认为所有用户都能访问-->  
    3. </authorization>  
     

     

        第三步、设置不同目录的访问方式。

        在《asp.net中的窗体身份验证(分目录验证篇)》中,曾经介绍过分目录的验证方式,这种方式是在目录中创建一个web.config文件,然后在web.config文件中的<system.web>和</system.web>小节中,添加“<authorization></authorization>”节点,在该节点中设置不让匿名用户访问。在这里,我们介绍另外一种设置不同目录的访问方式,假设,我们现在要指定admin目录不能让匿名用户访问,那么,我们可以在根目录的web.config文件的<system.web>和</system.web>中添加以下代码:

    [c-sharp] view plaincopy
    1. <location path="admin">  
    2.     <system.web>  
    3.         <authorization>  
    4.                 <!--拒绝所有匿名用户访问-->  
    5.                 <deny users="?"/>  
    6.         </authorization>  
    7.     </system.web>  
    8. </location>  
     

        在以上代码中,<location>节点的path参数用于说明要对哪个目录可以访问控制,而<authorization>节点的作用同样是用于设置具体的访问权限。在以上代码中,<deny>节点用于说明拒绝哪些用户访问,如果需要拒绝所有用户访问,那么就要使用到“<deny users="*"/>”代码;如果需要允许所有用户访问,那么就需要使用“<allow users="*"/>”代码。然而,在<deny>节点和<allow>节点中还可以设置拒绝或允许哪些角色的用户访问,设置方法为“<deny roles="admin"/>”或“<allow roles="admin"/>”。其中,roles参数用于说明指定的拒绝或允许访问的角色名,如果存在多个角色,则用逗号进行分割。在本例中,要求admin目录只能让admin角色的用户访问、backup目录可以让admin角色和backup角色的用户访问,user目录可以让所有能过身份验证的用户访问(无论是什么角色),可以使用以下代码进行设置:

    [c-sharp] view plaincopy
    1. <!--设置admin目录的访问权限-->  
    2. <location path="admin">  
    3.     <system.web>  
    4.         <authorization>  
    5.             <!--允许角色为admin的用户可以访问-->  
    6.             <allow roles="admin"/>  
    7.             <!--拒绝所有其他用户访问-->  
    8.             <deny users="*"/>  
    9.             <!--注意以上两句的次序不能变-->  
    10.         </authorization>  
    11.     </system.web>  
    12.  </location>  
    13. <!--设置backup目录的访问权限-->  
    14. <location path="backup">  
    15.     <system.web>  
    16.         <authorization>  
    17.             <!--允许角色为admin和backup的用户可以访问-->  
    18.             <allow roles="admin,backup"/>  
    19.             <!--拒绝所有其他用户访问-->  
    20.             <deny users="*"/>  
    21.             <!--注意以上两句的次序不能变-->  
    22.         </authorization>  
    23.     </system.web>  
    24. </location>  
    25. <!--设置user目录的访问权限-->  
    26. <location path="user">  
    27.     <system.web>  
    28.         <authorization>  
    29.             <!--拒绝所有匿名用户访问-->  
    30.             <deny users="?"/>  
    31.         </authorization>  
    32.     </system.web>  
    33. </location>  
     

     

        第四步、添加登录页面。

        由于在本例中,指定了网站目录中的login.aspx网页为登录面页,因此,在网站的根目录中添加一个login.aspx文件。然后在该文件中添加一个文本框(用于输入用户名)和一个密码框,再添加一个确定按钮。为了方便起见,我们假设用户名和密码都为1时,登录用户的角色为admin;用户名和密码都为2时,登录用户的角色为backup;用户名和密码都为3时,登录用户的角色为reader。登录网页中的代码如下所示:

    [c-sharp] view plaincopy
    1. //用户名  
    2. string UserName = TextBox1.Text;  
    3. //密码  
    4. string UserPassword = TextBox2.Text;  
    5. //用户角色  
    6. string UserRole = "";  
    7. //用户身份验证  
    8. if ((UserName == "1" && UserPassword == "1") || (UserName == "2" && UserPassword == "2") || (UserName == "3" && UserPassword == "3"))  
    9. {  
    10.     //判断用户权限  
    11.     switch (UserName)  
    12.     {   
    13.         case "1":  
    14.             UserRole = "admin";  
    15.             break;  
    16.         case "2":  
    17.             UserRole = "backup";  
    18.             break;  
    19.         case "3":  
    20.             UserRole = "reader";  
    21.             break;  
    22.     }  
    23.      
    24.     //创建一个身份验证票  
    25.     FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "yundao", DateTime.Now, DateTime.Now.AddMinutes(30), false, UserRole);  
    26.     //将身份验证票加密  
    27.     string EncrTicket = FormsAuthentication.Encrypt(ticket);  
    28.     //创建一个Cookie  
    29.     HttpCookie myCookie = new HttpCookie(FormsAuthentication.FormsCookieName, EncrTicket);  
    30.     //将Cookie写入客户端  
    31.     Response.Cookies.Add(myCookie);  
    32.     //跳转到初始请求页或默认页面  
    33.     Response.Redirect(FormsAuthentication.GetRedirectUrl("yundao"false));  
    34. }  
     

        以上代码和前面介绍过的身份验证代码类似,惟一不同的是将用户角色写在了身体验证票的用户数据(也就是FormsAuthenticationTicket()方法的最后一个参数)中。

     

        第五步、将用户角色添加到表示用户身份的GenericPrincipal对象中。

        经过上面的步骤,我们已经将用户的角色存放在身份验证票据中了,然而,此时用于表示用户身份的GenericPrincipal对象中却还只是包含了用户信息而不包含用户的角色信息。在这一步骤中,我们必须将用户角色信息存放到GenericPrincipal对象中。至于怎么样将用户角色信息存放到GenericPrincipal对象中呢,我们就必须要先了解一下用户验证与授权的过程了:

        1、客户端浏览器发送一个请求到服务器端。

        2、服务器端接收到请求之后,会先检查该请求中是否包含有可能存在的恶意标记,如果存在恶意标记则会返回错误信息。

        3、激活作为HTTP执行管线链中的第一个事件——BeginRequest事件。

        4、处理完BeginRequest事件之后,asp.net将会创建用户标识,此时激发AuthenticateRequest事件,该事件可以确保事件处理程序之前对请求进行身份验证。

        5、在AuthenticateRequest 事件之后,会继续触发PostAuthenticateRequest 事件,该事件同时是在asp.net创建用户标识时触发,但在该事件中可以访问由AuthenticateRequest事件中处理的任何数据。

        6、然后,asp.net会进入用户授权验证,此时会激发AuthorizeRequest事件。

        7、验证授权完毕之后,当用户获得了授权时,将会激发PostAuthorizeRequest事件。

        8、到第7步为止,整个用户身份验证就已经完毕了,接下来将会激发PostResolveRequestCache事件,在该事件之后还会有N个事件,直到向客户端返回信息为止。但那件事件都不是本文的重点,也就不详细介绍了。

     

        在用户登录确认身份之后,通常都会将身份验证票写到客户端的cookie中,然后客户端会将信息发送到服务器上,而在服务器端,asp.net会为每一个HTTP请求都分配一个HttpApplication对象,该对象的作用是处理HTTP请求的,也就是用来处理以上步骤的。从以上步骤中可以看出,身份验证是从AuthenticateRequest事件激发开始的,在该事件触发后,asp.net就会根据客户端发来的包含身份验证票的Cookie建立用户身份。

        而asp.net创建的用户身份包含在HttpContext.User属性中,可以使用“HttpContext.Current.User”来获得得这个用户身份。对于Forms验证而言,HttpContext.User属性是一个GenericPrincipal对象,该对象有两个重要的属性:第一个是Identity属性,该属性存放的是当前用户的标识。Identity属性就是一个FormsIdentity对象,该对象的Name属性可以用户标识、Ticket属性可以获得用户的身份验证票。另外,GenericPrincipal对象还有一个m_role属性,这个属性是GenericPrincipal对象的私有属性,所以不能通过GenericPrincipal.m_role来访问,该属性是一个数组,用于存放用户角色。如果想知道用户是否属于某个角色,可以通过GenericPrincipal 对象的IsInRole()方法来判断。然而,由于身份验证票中并没有提供m_role参数,因此,在asp.net创建用户身份时,用户是没有角色信息的。换句话而言,对于Forms身份验证而言,在默认情况下,GenericPrincipal对象的m_role属性为空。

     

        因此,如果想要使用角色的用户身份验证方式,就必须要在代表用户身份GenericPrincipal对象中添加用户角色。而且,这个工作必须要在第3个步骤中完成,因为第4个步骤的作用就是创建用户标识。因此,我们必须要在网站的根目录中创建一个Global.asax文件,Global.asax文件的作用就不用我再多说了了吧?

        在Global.asax文件中添加代码“protected void Application_AuthenticateRequest(object sender, EventArgs e)”用于处理AuthenticateRequest事件。处理步骤如下所示:

        1、首先判断用户的身份验证信息是否为空,如果HTTP请求中就没有用户身份验证信息,那么后面的步骤也就没必须进行了。前面介绍过,asp.net创建的用户身份包含在HttpContext.User属性中,因此,在该步骤中只需要判断HttpContext.User属性是否为空即可达到目的。

        2、然后判断用户是否已经通过了身份验证,如果没有通过身份验证,那么在访问受限网页时,asp.net会自动跳转到登录网页上。前面介绍过,HttpContext.User属性也就是一个GenericPrincipal对象,该对象的Identity属性值为用户标识,那么只要判断Identity.IsAuthenticated是否为true,就可以知道用户是否已经通过身份验证。

        3、由于asp.net的身份验证方式有多种,因此,在这里我们还要判断一下用户通过的身份验证方式是否为Forms验证方式。要达到该目的,只需要判断User.Identity是否为FormsIdentity对象即可。

        4、然后,可以获得已经通过了Forms身份验证的用户标识,再从该用户标识的身份验证票中获得用户数据(也就是包含了用户角色的字符串)。

        5、再然后,将用户角色字符串放到一个角色数组中——如果一个用户属于多个角色,通常我们都会将不同的角色使用逗号进行分割后放在用户数据中,然后将第4步骤中获得的用户数据分割后放在一个数组中,这样就得到了一个角色数组。

        6、最后,创建一个新的GenericPrincipal对象,在创建该对象时将从第4步骤中获得的用户标识以及第5步骤中获得的角色数组一起放入GenericPrincipal对象,然后将该对象赋值给HttpContext.User。

        这样,用户身份中就包含了角色信息。在随后的访问用,asp.net就会自动验证用户的角色以判断该用户是否可以访问限制的目录了。具体代码如下所示:

    [c-sharp] view plaincopy
    1. protected void Application_AuthenticateRequest(object sender, EventArgs e)  
    2. {  
    3.     //判断正在请求页的用户的身份验证信息是否为空  
    4.     if (HttpContext.Current.User != null)  
    5.     {  
    6.         //判断用户是否已经进行了身份验证  
    7.         if (HttpContext.Current.User.Identity.IsAuthenticated)  
    8.         {  
    9.             //判断当前用户身份验证的方式是否为Forms身份验证方式  
    10.             if (HttpContext.Current.User.Identity is FormsIdentity)  
    11.             {  
    12.                 //获得进行了Forms身份验证的用户标识  
    13.                 FormsIdentity UserIdent = (FormsIdentity)(HttpContext.Current.User.Identity);  
    14.                 //从身份验证票中获得用户数据  
    15.                 string UserData = UserIdent.Ticket.UserData;  
    16.                 //分割用户数据得到用户角色数组  
    17.                 string[] rolues = UserData.Split(',');  
    18.                 //从用户标识和角色组初始化GenericPrincipal类  
    19.                 HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(UserIdent, rolues);  
    20.             }  
    21.         }  
    22.     }  
    23. }  
     

     

        至此,一个完整的带角色控制的窗体身份验证就已经做完了。

    在前面的几篇文章中介绍了asp.net的窗体身份验证,这种身份验证方式可以让通过验证的用户访问指定的目录,而没有通过验证的用户不能访问该目录下的网页。

        但是,有一种例外,就是目录中的html文件例外。例如,在《asp.net中的窗体身份验证(最简单篇)》中介绍的,除了登录网页之外,所有网页都必须在登录之后才能访问,但如果在网站中添加一个HTMLPage.htm文件,访问该文件是不需要身份验证的。如下图所示:

        之所以出现这种情况,是由IIS的访问机制决定的。当客户端浏览器向Web服务器发送请求时,Web服务器会对所请求的文件的扩展名进行检查,然后决定由哪个ISAPI扩展处理这个请求,然后将请求传递给该ISAPI扩展。而asp.net事实上也就是一个ISAPI扩展,对于asp1.1而言,这个扩展文件为:C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/aspnet_isapi.dll,对于asp2.0而言,这个扩展文件为:c:/windows/microsoft.net/framework/v2.0.50727/aspnet_isapi.dll。

        很不幸的是:asp.net映身的扩展名有.aspx、.ascx、.ashx、.asmx,就是没有.htm和.html。所以,如果受限目录中包括.htm和.html网页时,asp.net是不会对其进行处理的。只要用户可以通过IIS的权限控制,就可以访问这些文件。

        找到原因就好办了,如果想要让.htm文件和.html文件也受asp.net控制,那么,就必须添加映射。添加方法如下所示:

        1、在IIS中找到网站或虚拟目录,右击,选择属性,打开如下图所示窗口。

        2、单击“配置”按钮,弹出下图窗口。

        3、单击“添加”按钮,打开如下窗口。

        4、在可执行文件中输入“C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/aspnet_isapi.dll”(asp.net1.1)或“c:/windows/microsoft.net/framework/v2.0.50727/aspnet_isapi.dll”(asp.net 2.0),在扩展名中输入“htm”或“html”,注意前面不用加“.”。然后点确定。

        5、重启一下IIS,再访问刚才的html文件,如下图所示,现在要求登录了,而且在URL中也可以看到ReturnUrl参数值为htm文件。

    原本是没打算写下这一篇的,因为觉得身份验证到了登出之后,就算完成了。可是后来有博友提出疑问,登出之后,点击浏览器上的后退按钮,还是可以退回到登出前页面,起不到身份验证的作用。

        事实上,就算使用后退按钮回到原来的页面,也只能看看页面内容,而不能对网页进行操作。一但进行操作的话,还是会需要重新登录的。

     

        也许,有些朋友对页面的安全性要求比较高,连看都不想让人家看到。那这要怎么办?

     

        这要从浏览器的缓存说起了。在N久以前,网络的宽带慢的是很慢很慢,所以,浏览器都有一个叫做“缓存”的功能。当你浏览了网页之后,就会把这个网页先缓存到本地计算机中,等你下一次再访问该网页时,浏览器会将缓存到本机计算机中的内容与服务器上的内容进行比较,如果没有更新,就不从服务器上读取网页,而是直接显示本地计算机中缓存的内容。这样做有两个好处,第一、客户端可以快速打开网页,节省等待的时间;第二、减少服务器压力。

        所以,这个功能就一直保留了下来,直到今天、明天或者后天。

     

        如果想不让浏览器缓存网页,最简单的方法就是使用HTML代码来实现,如以下代码所示。

    [xhtml] view plaincopy
    1. <meta http-equiv="Cache-Control" content="no-cache" />  
    2. <meta http-equiv="Pragma" content="no-cache" />  
    3. <meta http-equiv="Expires" content="-1" />  
     

        以上代码应该放在<head>和</head>之间,第一句是HTTP 1.1标准中支持的,让浏览器不缓存网页内容;第二句是HTTP 1.0标准中支持的,让浏览器不缓存网页内容。因为不知道用户浏览器支持什么标准,所以可以把两句都加上。第三句,指定是网页过期时间,一般来说content值都是指定的一个时间,在这个时间之前,浏览器会显示缓存中的内容,这个时间之后,才会从服务器中读取新内容。如果为0或负数,那么就说明浏览器永远都从服务器中读取网页内容。

     

        根据我十年前写HTML的经验,这样写就完全没有问题了。可是没想到的是……测试结果让我大跌眼镜、IE8、chrome6、Opera10和FireFox3.5下的测试全部没通过,点击浏览器的后退,还是可以看到登出后的网页。

     

        还好,我还有九年前编写ASP的经验,于是,在.CS文件中加入了以下代码:

    [c-sharp] view plaincopy
    1. //禁止客户端缓存服务器上的网页  
    2. Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);  
    3. //添加HTTP头  
    4. //HTTP 1.0标准,作用相当于<meta http-equiv="Pragma" content="no-cache" />  
    5. Response.AddHeader("pragma""no-cache");  
    6. //HTTP 1.1标准,作用相当于<meta http-equiv="Cache-Control" content="no-cache" />  
    7. Response.AddHeader("Cache-Control""no-cache");  
    8. //设置不缓存  
    9. Response.CacheControl = "no-cache";  
    10. //设置在浏览器上缓存的页面的过期时间  
    11. Response.Expires = -1;  
    12. //从缓存中移除的日期  
    13. Response.ExpiresAbsolute = DateTime.Now.AddSeconds(-1);  
     

        曾经,在ASP中使用了类似于以上代码的代码,那真是天下无敌,无论是IE浏览器还是Netscape浏览器(多让人怀念的浏览器啊),都能完美地实现不能后退的功能。

        美滋滋地进行了测试,这回,又让我跌了一次眼镜居然除了IE8(我没安装别的版本的IE)能实现不能后退的功能之外,chrome6、Opera10和FireFox3.5下的测试全部没通过。

     

        最后,我不得不使用asp.net的绝招了,在CS中加上以下代码:

    [c-sharp] view plaincopy
    1. Response.Cache.SetNoStore();  
     

        这回的测试结果还算满意,IE8、chrome6和FireFox3.5都通过测试,只有Opera10还是很顽强地从缓冲中读取网页内容。至于怎么让Opera浏览器也实现网页过期,目前我还没有找到方法。如果有哪位朋友知道的话,请告诉我,谢谢。

     

        在做测试时,以上代码写在子目录的测试页里,测试方法为:先进入登录页面-->登录后进入测试页面-->进入登出页面-->单击浏览器的后退按钮回退到测试页面。

        如果想在登出之后,使用后退按钮不能回退到任何一页,那么就可以在任何一个网页中加入以上代码。当然,还有一个简单的方法,在Global.asax文件中加入以下代码:

    [c-sharp] view plaincopy
    1. protected void Application_BeginRequest(Object sender, EventArgs e)  
    2. {  
    3.     HttpContext.Current.Response.Cache.SetNoStore();  
    4. }  
     

     

        最后,再建议一下,对于单个文件而言,最好在aspx文件中加上<meta>、在CS文件中将以上代码都加上,鬼才知道用户浏览器支持什么啊。还是宁多勿少吧。



http://m.blog.csdn.net/blog/smallfools_11109/4221118

0 0
原创粉丝点击