论坛交流
首页办公自动化| 网页制作| 平面设计| 动画制作| 数据库开发| 程序设计| 全部视频教程
应用视频: Windows | Word2007 | Excel2007 | PowerPoint2007 | Dreamweaver 8 | Fireworks 8 | Flash 8 | Photoshop cs | CorelDraw 12
编程视频: C语言视频教程 | HTML | Div+Css布局 | Javascript | Access数据库 | Asp | Sql Server数据库Asp.net  | Flash AS
当前位置 > 文字教程 > Asp.net教程
Tag:静态页面,treeview,gridview,repeater,dataset,sqldatareader,ado.net,上传,三层,ajax,xml,留言本,新闻发布,商城,注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,触发器,socket,form认证,登录,视频教程

从ASP.NET 1.1升级到ASP.NET 2.0需要考虑的Cookie问题

文章类别:Asp.net | 发表日期:2008-10-5 22:12:05

     当你准备将Web应用程序从ASP.NET 1.1升级到ASP.NET 2.0,你将面对这样一个cookie问题:在ASP.NET 1.1应用程序中客户端保存的所有cookie将失效。
      博客园也遇到了这样的问题,对博客园来说,意味着所有使用cookie的用户都需要重新登录,虽然这不是一个很大的问题,但的确给大家带来了麻烦,如果忘记了密码,将更加麻烦。
      对于一个非常重视用户满意度的网站来说,应该努力去解决这个问题。博客园希望尽可能减少升级带来的影响,所以这两天我一直在研究这个问题并找到了解决方法。
     问题的原因是:当程序从ASP.NET 1.1升级到于ASP.NET 2.0后,ASP.NET 2.0使用新的算法与密钥对客户端发送过来的cookie进行解密,这样导致ASP.NET中生成的cookie在ASP.NET 2.0中失效。在ASP.NET 1.1中,使用3DES算法对cookie的内容进行加密,而在ASP.NET 2.0中默认使用Advanced Encrypted Standards (AES)算法进行解密,这是引起问题的原因之一,通过相应的设置可以将ASP.NET 2.0中将cookie加密算法改为3DES,只需在web.config中加上:<machineKey decryption="3DES"/>。但这样做之后问题依然存在,因为解密时除了需要相同的算法,还需要相同的密钥。如果没有在machineKey中指定密钥,ASP.NET 2.0会默认会使用随机生成的密钥,这个随机密钥由System.Web.HttpRuntime.SetAutogenKeys()生成并存储于System.Web.HttpRuntime.s_autogenKeys中,通过反射你可以获取这个值。ASP.NET 1.1的machineKey是在machine.config中进行设置的,默认也是使用随机密钥:
<machineKey validationKey="AutoGenerate,IsolateApps" decryptionKey="AutoGenerate,IsolateApps" validation="SHA1"/>。
问题就出在不同的随机密钥上。如果你在原来的ASP.NET 1.1中指定了密钥,那就不存在这个问题了,但一般在使用Web farm时,才会考虑这一点。所以通常情况都是使用随机密钥。ASP.NET会为不同的应用程序生成不同的随机密钥,这个客户端cookie失效问题会出一在很多情况下,比如:重装系统、将ASP.NET应用程序移至另外一台计算机,将Web应用程序移到不同的虚拟目录中等等。
      如何解决这个问题呢?
      原理很简单,只要我们知道在ASP.NET 1.1中随机生成的密钥的值,然后在ASP.NET 2.0应用程序的web.config中进行指定就行了,这里的密钥有两个:一个是加密密钥decryptionKey,一个是散列计算密钥validationKey(防止cookie被中途篡改)。假如我们知道密钥分别为:X、Y,那在web.config
进行如下设置就能解决问题:
<machineKey validationKey="X" decryptionKey="Y" decryption="3DES"/>
      而难题就在于如何得到ASP.NET 1.1中随机生成的密钥的值。密钥存储在LSA(Windows Local Security Authority)中,但我没找到可以从LSA获取密钥的方法。
     由于博客园主要是解决登录cookie的问题,而这个cookie是在System.Web.Security.FormsAuthentication. SetAuthCookie(string userName, bool createPersistentCookie)中生成的,所以我就从ASP.NET 1.1的System.Web.Security.FormsAuthentication的源代码下手,发现了System.Web.Configuration.MachineKey,经过进一步对MachineKey的源代码进行研究,在MachineKey的MachineKeyConfig中发现了两个密钥分别存在于s_validationKey与s_oDes这两个私有静态成员中(发现这个费了不少功夫),validationKey的值直接存储于s_validationKey中,而decryptionKey存储于s_oDes.Key中。由于MachineKey是internal class,MachineKeyConfig是私有类型,那两个成员是私有静态成员,无法直接访问。这时,该是.NET中强大的反射功能发挥作用的时候了。通过反射得到这两个值,需要注意的是这两个值的类型是Byte[],通过测试发现直接转换成字符串生成的密钥无效,需要通过反射调用System.Web.Configuration.MachineKey.ByteArrayToHexString(Byte[], Int32) 转换成字符串。
     今天晚上终于解决了这个问题,好兴奋!中途几次想放弃,但想到在博客园程序升级到ASP.NET 2.0后,会因为这个问题给很多人带来麻烦,虽然只需要重新登录一下就行了,但我还是觉得要解决这个问题,做程序开发不就是尽可能给用户带来方便吗?
     解决了这个问题就为博客园网站升级到ASP.NET 2.0作好了进一步的准备。

出处:dudu-快乐程序员

视频教程列表
文章教程搜索
 
Asp.net推荐教程
Asp.net热门教程
看全部视频教程
购买方式/价格
购买视频教程: 咨询客服
tel:15972130058