当你准备将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中指定密钥,asp.net 2.0会默认会使用随机生成的密钥,这个随机密钥由system.web.httpruntime.setautogenkeys()生成并存储于system.web.httpruntime.s_autogenkeys中,通过反射你可以获取这个值。asp.net 1.1的machinekey是在machine.config中进行设置的,默认也是使用随机密钥:.问题就出在不同的随机密钥上。如果你在原来的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进行如下设置就能解决问题:而难题就在于如何得到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作好了进一步的准备。
新闻热点
疑难解答
图片精选