问题产生根源:

当然,其实应该需要保持线上所有机器环境一致!可是,写了一个小程序。使用的是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. [CareerCup] 13.5 Volatile Keyword 关键字volatile

    13.5 What is the significance of the keyword "volatile" in C 这道题考察我们对于关键字volatile的理解,顾名思义, ...

  2. Android WebRTC视频旋转问题

    最近在对接WebRTC到安卓手机上,有个需求就是手机横屏时将对方图像进行旋转,研究了WebRTC video_render的代码后发现远端的视频渲染使用opengles20或surfaceview实现 ...

  3. G - MPI Maelstrom

    题目大意: BIT最近要取会他们的超级计算机,32处理器阿波罗奥德赛与分层通信子系统分布式共享内存的机器(听着很高端大气),瓦伦丁*麦基的顾问杰克*斯威特告诉她基准测试的新系统.(没有明白什么意思) ...

  4. HDU3535-AreYouBusy

    描述: As having become a junior, xiaoA recognizes that there is not much time for her to AC problems, ...

  5. dpkg: error processing mysql-server (--configure): dependency problems - leaving unconfigured

    dpkg: error processing mysql-server (--configure): dependency problems - leaving unconfigured start: ...

  6. A - Space Elevator(动态规划专项)

    A - Space Elevator Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u ...

  7. leetcode每日刷题计划-简单篇day7

    还没有背单词,头晕脑胀 Num 66 加一 Plus One 注意就是进位的时候最后一位,为了省两句代码,那几个语句顺序写反覆盖的乱七八糟 vector头部插入(a.begin(),被插入的数) 如果 ...

  8. 数据结构之 栈 (Python 版)

    数据结构之 栈 (Python 版) -- 利用线性表实现栈 栈的特性: 后进先出 基于顺序表实现栈 class SStack(): ''' 基于顺序表 实现的 栈类 ''' def __init__ ...

  9. CodeM资格赛1

    题目描述 美团外卖的品牌代言人袋鼠先生最近正在进行音乐研究.他有两段音频,每段音频是一个表示音高的序列.现在袋鼠先生想要在第二段音频中找出与第一段音频最相近的部分. 具体地说,就是在第二段音频中找到一 ...

  10. C#中如何动态加载DockPanel

    在WinForm项目中要求实现动态加载DockPanel. 简单研究了下,演示代码如下: 很简单几行代码,实现了基本意图.看起来问题很快解决. 但是实际应用中发现几个问题: 1.当第一次运行时,doc ...