SSO:SSO英文全称Single Sign On,单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。
如果你的Asp.Net程序执行时碰到这种错误:"验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载,请确保 <machineKey> 配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate。”
那么说明你没有让你的应用程序使用统一的machineKey,那么machineKey的作用是什么呢?按照MSDN的标准说法:“对密钥进行配置,以 便将其用于对 Forms 身份验证 Cookie 数据和视图状态数据进行加密和解密,并将其用于对进程外会话状态标识进行验证。”
也就是说Asp.Net的很多加密,都是依赖于machineKey里面 的值,例如Forms 身份验证 Cookie、ViewState的加密。默认情况下,Asp.Net的配置是自己动态生成,如果单台服务器当然没问题,但是如果多台服务器负载均 衡,machineKey还采用动态生成的方式,每台服务器上的machinekey值不一致,就导致加密出来的结果也不一致,不能共享验证和 ViewState,所以对于多台服务器负载均衡的情况,一定要在每台站点配置相同的machineKey。
Asp.net User 中加密cookie, 有效的几个元素:machineKey,用户名,加密方法,域名(导致cookie的作用域).
A:在虚拟主机上,不同站长的站点都在同一台机器上,默认情况,machinekey是相同的,使用FormsAuthentication就有一点风险,有时为了安全,通常可以使用自己生成随机的machineKey,这样就避免了这个问题。
B:为了负载平衡,一个站点的不同内容放到不同的机器,这样默认情况,machineKey是不同的,但是逻辑上这些都是同一站点,为了实现多个机器共用同一登入,这时就要配置相同的machineKey。
1 using System.Web.Configuration; 2 ////打开web.config文件,写入新生成的machineKey 3 Configuration config = WebConfigurationManager.OpenWebConfiguration("/"); 4 MachineKeySection configSection = (MachineKeySection)config.GetSection("system.web/machineKey"); 5 configSection.ValidationKey = CreateKey(64); 6 configSection.DecryptionKey = CreateKey(24); 7 configSection.Validation = MachineKeyValidation.SHA1; 8 if (!configSection.SectionInformation.IsLocked) 9 { 10 config.Save(); 11 Response.Write("写入成功!"); 12 } 13 else 14 { 15 Response.Write("写入失败!段被锁定!"); 16 }
using System.Security.Cryptography; //生成随机Key public static string CreateKey(int numBytes) { RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); byte[] buff = new byte[numBytes]; rng.GetBytes(buff); System.Text.StringBuilder hexString = new System.Text.StringBuilder(64); for (int i = 0; i < buff.Length; i++) { hexString.Append(String.Format("{0:X2}", buff[i])); } return hexString.ToString(); }
例子:
1 <machineKey validationKey="3FF1E929BC0534950B0920A7B59FA698BD02DFE8" 2 decryptionKey="280450BB36319B474C996B506A95AEDF9B51211B1D2B7A77" 3 decryption="3DES" 4 validation="SHA1"/>
[证实] 在本地hosts里面将两个localhost站点分别设置为不同域名,当然端口是不同的,
此时,machineKey相同,用户名相同,还有authentication里面的加密方法也选择相同,
用A站点生成的cookie的值,在B站点也生成auth的cookie,结果B站点可否进入登入状态:
答案是: 可以登入.
用户名可以注册,authen cookie的加密方法就3种可以列举,因此 虚拟主机之上默认的machineKey还是有风险的)
1 if (cmd=="ticket") 2 { 3 string hashString=Context.Request["hash"]??""; 4 HttpCookie cookie=new HttpCookie(FormsAuthentication.FormsCookieName, hashString); 5 cookie.Expires=DateTime.Now.AddDays(1); 6 7 if (HttpContext.Current.Request.Cookies.AllKeys.Contains(FormsAuthentication.FormsCookieName)) 8 HttpContext.Current.Response.Cookies.Remove(FormsAuthentication.FormsCookieName); 9 HttpContext.Current.Response.Cookies.Add(cookie); 10 }