最近写了个WEB邮件系统,希望与已有的门户网站实现单点登录。
基本情况:
1.邮件系统采用Mvc4,使用Form身份认证。该系统单独运行没有任何问题。
登录部分代码
[AllowAnonymous]
[HttpPost]
public ActionResult Login(LoginModel model, string returnUrl) { if (Membership.ValidateUser(model.UserName, model.Password)) { FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe); if (!string.IsNullOrEmpty(returnUrl)) //if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } else { return RedirectToAction("Index", "Home"); } } else { ModelState.AddModelError("", "The user name or password provided is incorrect."); } } // If we got this far, something failed, redisplay form return View(model); }
2. 在与已有网站系统整合的时候,出现无法同步登录。
为了方便测试,添加了一个测试的控制器
public ActionResult Testlogin() { FormsAuthentication.SetAuthCookie("用户名", true, FormsAuthentication.FormsCookiePath); return RedirectToAction("Index", "Home"); }
在浏览器中直接访问 Testlogin 能够成功登录,并跳转到指定页面。
但在已有的门户网站中添加js代码,访问Testlogin,无法成功登录。跳转到指定页面显示cookie为空,User.Identity.Name 为空。
3. 我以为cookie写入错误,或者form认证存在问题,于是不使用SetAuthCookie,重写Testlogin,手动写入cookie。
[AllowAnonymous] public ActionResult Testlogin() { FormsAuthenticationTicket ticket = new FormsAuthenticationTicket( 1, "sssss", DateTime.Now, DateTime.Now.AddMinutes(20), false, "sssss"); // generate new identity FormsIdentity identity = new FormsIdentity(ticket); HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket)); // write to client. Response.Cookies.Set(cookie); HttpCookie cookie2 = Request.Cookies[FormsAuthentication.FormsCookieName]; return RedirectToAction("Index", "Home"); }
但是问题依旧存在。在浏览器中直接访问该Testlogin一切正常。
从其他网站用js请求Testlogin,经过调试,发现cookie能够设置到Request,但是在RedirectToAction后,在新的请求(Global.asax.cs中)
//AuthenticateRequest protected void Application_AuthenticateRequest() { // 1. 读登录Cookie HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName]; if (cookie == null || string.IsNullOrEmpty(cookie.Value)) { } else { try { LoginModel userData = null; // 2. 解密Cookie值,获取FormsAuthenticationTicket对象 FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value); if (ticket != null && string.IsNullOrEmpty(ticket.UserData) == false)
设置断点,跳转后,就丢失了cookie。
请大家帮忙看看,问题出在哪里??为什么cookie会丢失??
经过初步分析,该问题应该存在两个可能:
1.MVC3/4的Form验证机制不允许跨域请求?? 因为之前采用该方式能够与discuzNT整合。discuzNT采用web application。
2.浏览器不保存跨域请求的session和cookie。 需要进行特殊设置,比如增加 p3p header,已经写cookie有一定方式。
请有这方面经验的高手指点。。。。,谢谢。
1. ie不接受第三方cookie,所以在跨域的时候需要增加p3p头。
2. ie9对cookie删除(即失效)不明确。还有的时候自动启动新的进程,导致cookie不能访问,其实是进程间cookie不能访问。建议用其他浏览器调试。
3.对于cookie无效的时候,可以考虑使用数据库或其他方式保存用户状态。
问题的关键在:在已有的门户网站中添加js代码,访问Testlogin,无法成功登录。
所以重点是添加的js代码是什么。
谢谢回复。
门户上的登录 增加了js 向 Testlogin发送post请求数据,为了测试,Testlogin不处理任何数据直接写cookie都不成功。
备注:之前,门户网站已经与 discuzNT整合,也是使用该方法。discuzNT采用的aspx web程序,不是MVC Form验证。
子域共享Cookie的话得设置Cookie的Domain一致,可以在Web.Config的<system.web>下设置<httpCookies domain="你的Domain"/>。
考虑过设置 domain。没有作用。
只要跳转后,就没有cookie了。
请问楼主怎么解决的啊,我也遇到这样的问题!
不好意思,好久没有来了。
我也遇到这问题,请楼主分享解决办法。谢谢!
后来在服务端请求了。不要在客户端请求。