zoukankan      html  css  js  c++  java
  • Asp.Net的Forms验证,解决Cookie和Seesion失效时间。

    网站开发中用户验证一般采用Asp.Net的Forms验证,验证票据存储到Cookie的方式。

        Session方式是将验证信息存储在内存中,如果你使用的虚拟主机给你分配很小的内存,实际上都是如此,那么session就会很快过期,要求你重新登录,如果用户正在填写信息,被要求重新登录,那愤怒的感觉可想而知。

       cookie是存储在用户的客户端的。但是也会碰到失效的问题,下面一一来了解。

        在ASP.NET Forms验证中,通常我们会使用ASP.NET自带的Login控件来进行验证。同时,在web.config文件中,我们所有的Forms设置都设为默认。现在,问题就来了。

    1.为什么我明明点了"Remember me",而大概半个小时后,我又Log out了?

    2.为什么我明明设置了timeout为无限期 e.g. 400000,为什么一两天之后我又Log out了呢?

    这是Forms验证中遇到的比较多的问题。下面,我就这两个问题做一个详细的解释:对于问题一,首先我要阐明ticket和cookie的区别。cookie是一个容器,用来存放东西,它是保存在客户端的。而ticket是具体的数据,用来表示具体的验证信息,它是放在cookie这个容器中的。因而,在我们验证的过程中,以下事情发生了。首先,ticket被创造了,里面包含着用户名等信息,同时它有一个过期时间。

        然后,cookie被创造了,它同样也有一个过期时间。最后,将ticket保存在cookie中,并将此cookie发送到client的浏览器中。读到这里,我想问题已经很明白了,用户的Log out就是因为时间过期的问题。但具体是谁的时间过期了呢?在我们ASP.NET web.config的设置中,timeout是cookie的过期时间(注意,默认是30分钟),而ticket的过期时间是无限的,因为我们选了"Remember me".这就是为什么虽然我点了"Remember me"。

        但在30分钟左右后,我仍然被Log out了,因为我们并没有设置cookie的timeout.ticket和cookie,只要其中之一不是永远不过期,我们都无法实现永不过期。  

        当我们解决了问题一后(假如手动设置timeout="4000000"),我们又遇到了问题二。这又是什么原因呢?这得从ticket的加密解密机制说起。ASP.NET会使用一个machinekey来对cookie进行加密,这个machinekey默认是在application启动时随机生成的。然后,ASP.NET会使用同一个machinekey进行cookie进行解密。正式因为这个key是application启动时随机生成的才导致了问题二。试想,如果application recycle(重启)了怎么办?

    ASP.NET会生成另一个key进行解密,以前的cookie将不再有效,这就是问题二的原因了。知道了这个,解决第二个问题的办法就很简单了,手动设置一个特定的key.如:<machineKey validationKey="88CB6CA6CF403C5FBB41C2F62BB7FCFCA05DE7BE" decryptionKey="B8A7CF3816C57176" validation="SHA1" />

    实现Asp.net Forms身份验证的操作步骤
    对于应用程序的身份验证,一直是自已编写登陆窗体,在窗体的CS文件中判断用户的登录是否合法,如果合法则将用户名保存在Cookie中。然后将所有页面的继承于一个类似BaseForm这样的基页面,在这个页面的Page_Load事件中加入判断,根据Cookie来判断用户是否已登录,如果没有登录则跳转到登录页面。
    最近作一个互连网网站,想起安全性的问题,查阅了一些资料后觉得采用Asp.net提供的标准的Forms验证方式。研究了一下,现在写出操作步骤,以供以后使用的时候参考(博客现在的一个很重要的功能就是用来保存曾经的学习积累)
    1、 修改web.config文件。如果vs2005的话,默认没有这个文件,调试时才会提示你是否要添加该文件。在web.config文件的<system.web>节中添加下面的三部分内容:
    <authentication mode="Forms">
           <forms loginUrl="default.aspx" name=".ASPXFORMSAUTH">
           </forms>
         </authentication>
         <authorization>
           <deny users="?" />
         </authorization>
        <machineKey
        validationKey="AutoGenerate,IsolateApps"
        decryptionKey="AutoGenerate,IsolateApps"    
        validation="SHA1"
        decryption="Auto" />
    上面三部分分别标有不同颜色,第一部分是设定应用程序的身份验证模式,默认是windows,如果你的系统是在局域网内使用,并且整个局域网是工作在域模式下,那windows身份验证方式将会有很好的效果,如果多个B/S用windows模式来进行身份验证,那么他们甚至可以非常方便的就实现了单点登陆的效果。但Forms身份验证使用的更普遍些,虽然相对来说他存在安全性差的问题。在authentication节下有个forms节,在那里你可以填上执行你身份验证的页面,以及存储身份验证所采用的Cookie名称。如果你不填写Cookie名称的话,Asp.net默认分配.ASPXFORMSAUTH作为Cookie名称。
        第二部分authorization是授权部分。你可以配置允许或拒绝某些用户或者角色来访问你的应用程序,他下面有deny,allow可以使用,搭配通配符?、*让我们可以非常轻易的配置出轻量级简单的身份验证体系。详细的配置信息可以参照asp.net的帮助文档,在此不在详细描述。
        第三部分machineKey是用来配置存取Cookie时采用的加密/解密算法。有了这个算法后,Cookie应该算是比较安全了吧。
    2、 将Cookie信息登录后保存起来。
    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1,CookieInfoDateTime.Now,DateTime.Now.AddHours(20),false,UserData); // User data
            string encryptedTicket = FormsAuthentication.Encrypt(authTicket); //加密
            //   存入Cookie
            HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName,encryptedTicket);
             authCookie.Expires = authTicket.Expiration;
             Response.Cookies.Add(authCookie);
    首先创建一个身份票据,身份票据主要保存用户的名称,Cookie的过期时间,另外你还可以保存一些额外数据,比如用户所扮演的角色。这里有个地方要注意,UserData是用来保存一些额外数据,比如角色,但如果我没有数据的话,通常会传一个null值进去,但如果你是想将Cookie信息进行加密保存的话,这里不能传null值,你可以传一个””值。如果传null值的话,在执行string encryptedTicket = FormsAuthentication.Encrypt(authTicket); 的时候会返回一个null值,以至于生成一个错误的加密Cookie值。如果要将Cookie进行长期保存,需要为Cookie设置一个过期时间。
    3、 读取保存在计算机中的Cookie。
    在Global.asax 文件中存在Application_AuthenticateRequest事件,它是执行所有服务器端请求的时候执行。因此我们可以在这个地方读取Cookie并进行解密。以下是示例代码:
    protected void Application_AuthenticateRequest(object sender, EventArgs e)
         {
            string cookieName = FormsAuthentication.FormsCookieName;//从验证票据获取Cookie的名字。
            //取得Cookie.
            HttpCookie authCookie = Context.Request.Cookies[cookieName];
            if (null == authCookie)
                return;
            FormsAuthenticationTicket authTicket = null;
            //获取验证票据。
             authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            if (null == authTicket)
                return;
           
            //验证票据的UserData中存放的是用户角色信息。
            //UserData本来存放用户自定义信息。此处用来存放用户角色。
            string[] roles = authTicket.UserData.Split(new char[] { ',' });
            FormsIdentity id = new FormsIdentity(authTicket);
            GenericPrincipal principal = new GenericPrincipal(id, roles);
            //把生成的验证票信息和角色信息赋给当前用户.
             Context.User = principal;
         }
    当你对Cookie加密存储之后必须要进行解密后才能进行使用。
    4、 在每个页面读取Cookie的值。可以通过下面的语句来读取Cookie的值。HttpContext.Current.User.Identity.Name
     
    原文地址:http://blog.csdn.net/vasun/article/details/5100743
     
  • 相关阅读:
    解决 搭建Jekins过程中 启动Tomcat的java.net.UnknownHostException异常
    射手和农场主
    java 和 JS(javaScript)中的反斜杠正则转义
    分享修改密码的SharePoint Web part: ITaCS Change Password web part
    分享微软官方Demo用的SharePoint 2010, Exchange 2010, Lync 2010虚拟机
    Office 365 的公共网站的一些限制及解决的办法
    SharePoint 2013 关闭 customErrors
    安装 KB2844286 导致SharePoint 2010 XSLT web part 显示出现错误
    安装Office Web Apps Server 2013 – KB2592525安装失败
    如何将hyper-v虚拟机转换成vmware的虚拟机- 转换SharePoint 2010 Information Worker Demonstration and Evaluation Virtual Machine (SP1)
  • 原文地址:https://www.cnblogs.com/laihuayan/p/2962504.html
Copyright © 2011-2022 走看看