zoukankan      html  css  js  c++  java
  • 【原创】Cookie应用(二)

    Cookie的作用很大,在很多技术方案中都有应用。它也是Forms身份认证模式所使用的一门技术点。

    今天我就说一说它在Forms身份认证模式中都起到什么作用。

    (一)理论知识

    ASP.NET 使用身份验证提供程序实现附加的身份验证方案,这些身份验证提供程序独立于 IIS 身份验证方案并且只用于 IIS 身份验证方案之后。ASP.NET 支持下列身份验证提供程序:

    • Windows(默认)
    • Forms
    • Passport
    • None

    若要启用 ASP.NET 应用程序的身份验证提供程序,请使用 machine.config 或 Web.config 中的身份验证元素,如下所示:

    • <system.web>   <!-- mode=[Windows|Forms|Passport|None] -->   <authentication mode="Windows" /></system.web>
      每个 ASP.NET 身份验证提供程序都支持 OnAuthenticate 事件,该事件在身份验证过程中发生,您可以使用该事件实现自定义的身份验证方案。该事件的主要目的是将实现 IPrincipal 接口的自定义对象附加到上下文中

    上面引用了MSDN中的定义。

    二:Forms身份认证

    Forms 身份验证提供程序是一个身份验证方案,它使应用程序可使用 HTML 窗体直接从客户端收集凭据。客户端直接向应用程序代码提交凭据以进行身份验证。如果应用程序验证该客户端的身份,则它向该客户端发出一个 cookie,该客户端在后面的请求中提交该 cookie。如果对于受保护资源的请求不包含该 cookie,则应用程序将该客户端重定向到登录页。当验证凭据时,应用程序可以用多种方法存储凭据,如配置文件或 SQL Server 数据库。有关更多信息,请参见 Forms 身份验证提供程序

    注意   ISAPI 服务器扩展仅处理那些它拥有其应用程序映射的资源。例如,ASP.NET ISAPI 服务器扩展仅拥有特定资源(如 .asax、ascx、.aspx、.asmx 和 .config 文件,这里只给出这几个)的应用程序映射。默认情况下,ASP.NET ISAPI 服务器扩展以及随后的 Forms 身份验证提供程序不处理任何对非 ASP.NET 资源(如 .htm、.jpg 或 .gif 文件)的请求。

    优点

    • 允许使用任意条件自定义身份验证方案。
    • 可用于身份验证或身份确认。
    • 不需要相应的 Windows 帐户。

    缺点

    • 受制于 cookie 生存期的重放攻击,除非使用 SSL/TLS。
    • 仅适用于映射到 Aspnet_isapi.dll 的资源。

    同样引用MSDN,接下来就用具体代码实现其功能。

    (三)一步一步实现Form认证模式

    第一步:配置

    在Web.Config中配置如下 

    <system.web>

      <authentication mode="Forms">
         <forms cookieless="UseCookies" name="LoginCookieName" loginUrl="Login.aspx"></forms>      
      </authentication>

     </system.web>

    第二:设置登录凭证

    新建立页面Login.aspx,代码如下

    前台

     1      <table>
     2         <tr>
     3             <td>登录名:</td>
     4             <td><asp:TextBox ID="txtName" runat="server"></asp:TextBox></td>
     5         </tr>
     6         <tr>
     7             <td>密码</td>
     8             <td><asp:TextBox ID="TextBox1" runat="server"></asp:TextBox></td>
     9         </tr>
    10          <tr>
    11             <td colspan="2"><asp:Button ID="Button1" runat="server" Text="提 交" onclick="Button1_Click" /></td>        
    12         </tr>
    13      </table>

    后台

     1  protected void Page_Load(object sender, EventArgs e)
     2         {
     3             if (!IsPostBack)
     4             {
     5                 if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
     6                     Response.Redirect("Test1.aspx");
     7             }
     8         }
     9 
    10         protected void Button1_Click(object sender, EventArgs e)
    11         {
    12             FormsAuthentication.SetAuthCookie(txtName.Text, false);
    13         }

    创建一个测试页Test1.aspx

     1 <form id="form1" runat="server">
     2     <div>
     3       用户名:
     4       <asp:Label runat="server" ID="lblUserName"></asp:Label>
     5       已登录
     6       
     7       <asp:Button runat="server" ID="btnLoginOut" Text="退 出" 
     8             onclick="btnLoginOut_Click" />
     9     </div>
    10     </form>

    后台

     1  protected void Page_Load(object sender, EventArgs e)
     2         {
     3             if (!IsPostBack)
     4             {
     5                 if (Request.Cookies[FormsAuthentication.FormsCookieName] == null)
     6                     Response.Redirect("Login.aspx");
     7                 else
     8                 {
     9                     lblUserName.Text = Request.Cookies[FormsAuthentication.FormsCookieName].Name.ToString();
    10                 }
    11             }
    12         }
    13 
    14         protected void btnLoginOut_Click(object sender, EventArgs e)
    15         {
    16             FormsAuthentication.SignOut();
    17         }

    我们直接运行Login.aspx进行登录,然后再运行Test1.aspx,显示结果如下:

    用户名: LoginCookieName 已登录

    LoginCookieName正是我们在Web.Config中配置的name的值吗。再利用firefox的自带工具查看一下本页的Cookie值

    名称  LoginCookieName

    值   E446C4B9D24D0F623023D6563D64C64AC082A41D685F28CEE9AE4CEEDFD0FFEE0D845EEADEC13FC81F33CA7E4E6B28291E95273A813C2D216C67

    34E4D752D0F2CAA5F4B11ACA9FC355765810AFF2B0AFAACCD7AAFD04DD669C0CB52112EC277BC9347B1F

    主机  localhost

    路径   /

    加密   否

    到期  会话期间完即失效

    结果确认Form认证模式,其实就是利用Cookie的机制实现的。

    是否经过认证我们还可以下面的代码来判断

     if (Request.IsAuthenticated)
                    {
                        Response.Redirect("Test1.aspx");
                    } 

    (四)同域下Cookie共享问题

    有的时候往往会累到同域下共享Cookie的一系列问题,我总结一下基本出现的问题。

    情况一:比如在主域登录后,在二级域中不作为一个已验证的用户,相反也是如此。

    例如:主域名www.test.com,二级域名pass.test.com,如果我们在www.test.com中输入用户名/密码进行认证,认证成功后我们用代码FormsAuthentication.SetAuthCookie来设置Cookie,Cookie的域名往往被认为是www.test.com,我们再访问pass.test.com时,它的域名默认是pass.test.com,因为Cookie和domain(域名)是相关联的,如果在请求中域名不一致,Cookie将被忽略因些,我们在设置Cookie时,请使用以下代码:

     FormsAuthentication.SetAuthCookie(txtName.Text, false);
                HttpCookie lcookie = Context.Response.Cookies[FormsAuthentication.FormsCookieName];
                lcookie.Domain = ".test.com";
                Response.Redirect(FormsAuthentication.GetRedirectUrl(txtName.Text, false));

    情况二:主域和二级域不能同时注销问题

    根据情况一的解释,我们同理可以推出,如何注销了吧,代码如下:

                FormsAuthentication.SignOut();
                HttpCookie lcookie2 = Context.Response.Cookies[FormsAuthentication.FormsCookieName];
                lcookie2.Domain = ".test.com";
                Response.Redirect("user.aspx");

    (五) 自定义登录

    上面可能一起我们在使用FormsAuthentication.SetAuthCookie来实现Form认证,其实我们还有另一种方式。代码如下

    1 FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
    2    2, "NewLog", DateTime.Now, DateTime.Now.Add(10d), false, string.Empty);
    3   string str = FormsAuthentication.Encrypt(ticket);
    4 
    5 
    6   HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, str);
    7   Response.Cookies.Add(cookie);

    其效果和FormsAuthentication.SetAuthCookie是一样的。这样写可能更灵活。
    还可以自定义一些用户特定信息。这个我们将在下一章来讲。

     转载的请注原创地址,谢谢。

  • 相关阅读:
    20145316许心远《Java学习笔记(第8版)》课程总结
    小棒组合第三周项目总结
    20145316《Java程序设计》第十周学习总结
    20145316第五次实验报告
    20145316《Java程序设计》第9周学习总结
    20145316第四次实验报告
    20145316 《Java程序设计》第8周学习总结
    MyBatis 的基本介绍及使用
    JPQL 的基本使用
    JPA API与注解
  • 原文地址:https://www.cnblogs.com/yxhblog/p/2553828.html
Copyright © 2011-2022 走看看