最近项目中将一个网站的项目拆开,根据功能不同简历不同的项目。但是最后要在一个网站域名下。这就用到了虚拟目录。
同时遇到了一个困扰了我一天的问题,虽然最后不算是什么大问题,但是却把cookies和Forms身份验证的原理又重新研究了一番。还是基础,在此记录。
要求:登录主站之后,分站不用登录,直接进入。即单点登录。
背景:iis7中建立主站,主站中有分站的应用程序(即虚拟目录)。
使用标准的asp.net FormsAuthentication身份验证方式。登录代码如下:
RMS_LoginName rln = obj.ResultsObject as RMS_LoginName;
FormsAuthentication.SetAuthCookie(rln.Login_ID.ToString(),false);
HttpCookie cookie = FormsAuthentication.GetAuthCookie(rln.Login_ID.ToString(), false);
FormsAuthenticationTicket oldTicket = FormsAuthentication.Decrypt(cookie.Value);
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(1, oldTicket.Name, oldTicket.IssueDate, DateTime.Now.AddMinutes(30), oldTicket.IsPersistent, rln.ToString(), FormsAuthentication.FormsCookiePath);
cookie.Domain = cookie.Domain;
cookie.Path = "/";
cookie.Expires = DateTime.Now.AddMinutes(30);
cookie.Value = FormsAuthentication.Encrypt(newTicket);
HttpContext.Current.Response.Cookies.Add(cookie);
主站和分站两个应用程序web.config 配置相同
<authentication mode="Forms" >
<!--以下登录地址根据登录框页面真实地址修改-->
<forms loginUrl="/login.html" name="CotMainCenter" timeout="1800" defaultUrl ="/index.html" domain=".cotlife.cn" enableCrossAppRedirects="false" cookieless="UseDeviceProfile" />
</authentication>
问题来了:主站登录之后,分站无论如何不是登录状态。Context.User.Identity.IsAuthenticated始终未false
第一步:设置相同的domain,不好使。查找各种网上的资料,均不得要领。
第二步:调试分站PostAuthenticateRequest事件,中发现。Cookie丢失。
第三步:对比主站Request请求和奋战
第四步:使用浏览器调试,发现headers中Cookie包含登录的CotMainCenter。但是为啥没解析出来呢。
第五步:调试分站BeginRequest事件,中发现Cookie是有CotMainCenter的。
第六步:怀疑是分站解析Cookie时没解析成功。 那么为啥相同的Cookie在主站可以解析,分站不可以解析呢?有可能是不同的应用程序解析方式不一样?
第七步:终于在微软MSDN上找到了。http://msdn.microsoft.com/zh-cn/library/eb0zx8fc.aspx跨应用程序进行Forms身份验证。
在web.config中加入
<machineKey validationKey="C50B3C89CB21F4F1422FF158A5B42D0E8DB8CB5CDA1742572A487D9401E3400267682B202B746511891C1BAF47F8D25C07F6C39A104696DB51F17C529AD3CABE" decryptionKey="8A9BE8FD67AF6979E7D20198CFEA50DD3D3799C77AF2B72F" validation="SHA1" />
问题解决。
总结:不同的应用程序,在解析cookie时需要有相同的machinekey。当然machinekey需要自己生成。
但是为啥我的是同一个机器,machineKey会不一样呢?这个一开始就没考虑。现在还是有点糊涂。期待高手给解答一下。