问题产生根源:

当然,其实应该需要保持线上所有机器环境一致!可是,写了一个小程序。使用的是4.5,aysnc/await实在太好用了,真心不想把代码修改回去。

so,动了念头,在这台服务器上装个4.5,ms不是说了么,4.5和4.0是高度兼容的。。。。。。

问题现象:

一台服务器在安装.net framework 4.5 之后,在该服务器所部署的网站(使用.net framework 4,未修改任何配置,分布式环境),

网站在这台服务器上登录之后,打开其他服务器的任何站点,form验证过不去,导致重复登录,反之亦然.

问题分析:

为什么会导致重复登录问题?

很简单能推断出是在这个机器上安装了4.5 ,某些组件的变动,导致form验证的加解密方式有变动.使得2台机器生成的登录cookie内容不一致,不能相互解析.

能影响到.net对form加解密产生不同作用的地方无非2个.

1.本身代码的bug,兼容性问题问题。

2.配置影响(如web.config中的authentication,machineKey等).

1嘛,基本不可能,ms没这么渣,那就只能从2下手,但是具体什么配置影响到,就不得而知了.

通过参数配置,如果有改变,那对加解密产生的改变都是相符的. so,我们分析一下加密的方法,找出不同,通过参数来兼容这些修改.那问题就解决了.

form验证相关的方法,都在System.Web.Security.FormsAuthentication中.

通过调用加密方法在4.5上生成加密字符串,丢到4.0的机器上解密,不通过,提示加密字符串验证不通过.

so,我们看看加密方法中做了什么

加密方法:

省略部分代码,剩下的关键代码。

public static string Encrypt(FormsAuthenticationTicket ticket)
{
return Encrypt(ticket, true);
}
internal static string Encrypt(FormsAuthenticationTicket ticket, bool hexEncodedTicket)
{
byte[] clearData = MakeTicketIntoBinaryBlob(ticket);
if ((_Protection == FormsProtectionEnum.All) || (_Protection == FormsProtectionEnum.Encryption))
{
clearData = MachineKeySection.EncryptOrDecryptData(true, clearData, null, 0, clearData.Length, false, false, IVType.Random);
}
}
return CryptoUtil.BinaryToHex(clearData);
}

然后我们继续深入到MakeTicketIntoBinaryBlob中查看

private static byte[] MakeTicketIntoBinaryBlob(FormsAuthenticationTicket ticket)
{
if (!AppSettings.UseLegacyFormsAuthenticationTicketCompatibility)
{
return FormsAuthenticationTicketSerializer.Serialize(ticket);
}
  ........................
}

对比4,4.5中MakeTicketIntoBinaryBlob方法代码,发现4.5的源代码中多了AppSettings.UseLegacyFormsAuthenticationTicketCompatibility这么一个开关配置.

系统默认值为flase,so.在4.5中得到的加密字符串来自FormsAuthenticationTicketSerializer.Serialize(ticket).而4中是在后续代码中.

so,增加配置<add key="aspnet:UseLegacyFormsAuthenticationTicketCompatibility" value="true" /> 兼容到这部分.

然后,我们继续看MachineKeySection.EncryptOrDecryptData(true, clearData, null, 0, clearData.Length, false, false, IVType.Random);

internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length, bool useValidationSymAlgo, bool useLegacyMode, IVType ivType)
{
return EncryptOrDecryptData(fEncrypt, buf, modifier, start, length, useValidationSymAlgo, useLegacyMode, ivType, !AppSettings.UseLegacyEncryption);
}

很熟悉,又看到!AppSettings.UseLegacyEncryption开关配置.进入EncryptOrDecryptData方法中能看到这个参数影响到使用不同的加密方式.

同上,增加配置<add key="aspnet:UseLegacyEncryption" value="true" />兼容到这部分.

再次调用Encrypt方法生成加密字符串,丢到4.0机器上.哇,能解密成功了.

当然,实际解决起来,走了不少弯路,周五晚上发现问题,查了一晚上,未果,但是有思路了.后又周一查了2个小时,终于搞定这个问题.

相关说明:

有关安全更新 2638420 的部署指南,请参见 MS11-100

如何配置 ASP.NET 中的旧加密模式

看了上面一个,好傻...如果发现问题的时候,之后搜索asp.net 旧加密方式. 马上解决...

Asp.Net Form验证不通过,重复登录的更多相关文章

  1. Asp.Net Form验证不通过,重复登录(.net4,4.5form验证兼容性问题)

    问题产生根源: 当然,其实应该需要保持线上所有机器环境一致!可是,写了一个小程序.使用的是4.5,aysnc/await实在太好用了,真心不想把代码修改回去. so,动了念头,在这台服务器上装个4.5 ...

  2. [Asp.Net] Form验证中 user.identity为false

    这个方法可以是user.identity设置为true FormsAuthentication.SetAuthCookie(Username, true); 但是要开启form验证, 在配置文件中 & ...

  3. asp.net form 验证方式的使用(转载)

    如何运用 Form 表单认证 ASP.NET 的安全认证,共有“Windows”“Form”“Passport”“None”四种验证模式.“Windows”与“None”没有起到保护的作用,不推荐使用 ...

  4. 从零开始实现asp.net MVC4框架网站的用户登录以及权限验证模块 详细教程

    从零开始实现asp.net MVC4框架网站的用户登录以及权限验证模块 详细教程   用户登录与权限验证是网站不可缺少的一部分功能,asp.net MVC4框架内置了用于实现该功能的类库,只需要简单搭 ...

  5. ASP.net 实现禁止用户重复登录

    本文先为大家介绍如何利用缓存Cache方便地实现此功能. Cache与Session这二个状态对像的其中有一个不同之处,Cache是一个全局对象,作用的范围是整个应用程序,所有用户:而Session是 ...

  6. asp.net 身份验证-Form 身份验证

    一. .net身份验证简介 1.身份验证就是检测用户是否登录及所访问的资源是否有权限.当我们在访问一个受保护网络资源时,往往需要输入用户名.密码信息,或通过其他证书.第三方身份验证等方式.验证(Aut ...

  7. ASP.NET MVC Form验证

    一.前言 关于表单验证,园子里已经有不少的文章,相信Web开发人员也都基本写过,最近在一个个人项目中刚好用到,在这里与大家分享一下.本来想从用户注册开始写起,但发现东西比较多,涉及到界面.前端验证.前 ...

  8. ASP.NET Form身份验证方式详解

    注:不会涉及ASP.NET的登录系列控件以及membership的相关话题, 我只想用比较原始的方式来说明在ASP.NET中是如何实现身份认证的过程.   ASP.NET身份认证基础 在开始今天的博客 ...

  9. django登录注册验证之密码包含特殊字符,确认密码一致实现,Form验证

    Form验证的原理 首先用户在注册界面提交表单,后台收到表单之后通过request.post取到数据然后传入已经写好的Form类 执行obj.is_valid()这里的obj为Form的实例,在For ...

随机推荐

  1. Asp.net MVC 学习系列(一)序

    题外话 公司本月开始提供早餐服务,2块天一餐,包括粥,两个包(听说是利口福供应的),一个鸡蛋.良心企业.公司原本有一个内部订餐系统,用Delphi开发的,开发的人早就走光了,也没有留下什么文档,现在项 ...

  2. POJ2796Feel Good[单调栈]

    Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13376   Accepted: 3719 Case T ...

  3. KEngine:Unity3D资源的打包、加载、调试监控

    资源模块做什么? 资源模块——ResourceModule,是KEngine中最核心的模块,其他模块基本或多或少的对它有依赖,它主要的功能是:资源打包.路径定义.资源管理.资源调试. 资源模块对Uni ...

  4. 升级Flash Builder 4.6中的Flash Player版本

    测试有效 本人按此方法升级到了flash player 15 Adobe自发布Flash Builder 4.6后,就暂停了Flash Builder新版本的发布.但AIR和FlashPlayer版本 ...

  5. 万能的 SQL编程

    简介:T-SQL语句创建库.创建表和听.和添加约束等.T-SQL是数据库结构化查询语言,常见的增加.删出.修改.查询.创建库和创建表的语句,还支持定义变量.输出语句.逻辑控制语句(IF.CASE.WH ...

  6. background-origin 设置背景图片原始起始位置

  7. O(1) 查询gcd

    我们来安利一个黑科技.(其实是Claris安利来的 比如我现在有一坨询问,每次询问两个不超过n的数的gcd. n大概1kw,询问大概300w(怎么输入就不是我的事了,大不了交互库 http://mim ...

  8. js profiler

    https://developers.google.com/web/fundamentals/performance/critical-rendering-path/?hl=en https://de ...

  9. tcpip的可靠性

             

  10. Power of Two

    Given an integer, write a function to determine if it is a power of two. bool isPowerOfTwo(int n) { ...