首页 新闻 会员 周边

mvc3/Mvc4使用Form认证遇到一个奇怪的问题(SetAuthCookie,跨域多点登录,cookie丢失)?

0
悬赏园豆:20 [已解决问题] 解决于 2012-09-05 17:36

最近写了个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有一定方式。

 

请有这方面经验的高手指点。。。。,谢谢。

 

 

兮的主页 | 初学一级 | 园豆:188
提问于:2012-09-03 04:03
< >
分享
最佳答案
1

1. ie不接受第三方cookie,所以在跨域的时候需要增加p3p头。

2. ie9对cookie删除(即失效)不明确。还有的时候自动启动新的进程,导致cookie不能访问,其实是进程间cookie不能访问。建议用其他浏览器调试。

3.对于cookie无效的时候,可以考虑使用数据库或其他方式保存用户状态。

| 初学一级 |园豆:188 | 2012-09-05 17:34
其他回答(4)
0

问题的关键在:在已有的门户网站中添加js代码,访问Testlogin,无法成功登录。

所以重点是添加的js代码是什么。

收获园豆:10
Zigzag | 园豆:70 (初学一级) | 2012-09-03 10:28

谢谢回复。

门户上的登录 增加了js 向 Testlogin发送post请求数据,为了测试,Testlogin不处理任何数据直接写cookie都不成功。

备注:之前,门户网站已经与 discuzNT整合,也是使用该方法。discuzNT采用的aspx web程序,不是MVC Form验证。

支持(0) 反对(0) | 园豆:188 (初学一级) | 2012-09-03 15:19
0

子域共享Cookie的话得设置Cookie的Domain一致,可以在Web.Config的<system.web>下设置<httpCookies domain="你的Domain"/>。

收获园豆:10
webaspx | 园豆:1973 (小虾三级) | 2012-09-03 13:41

考虑过设置 domain。没有作用。

只要跳转后,就没有cookie了。

支持(0) 反对(0) | 园豆:188 (初学一级) | 2012-09-03 15:19
0

请问楼主怎么解决的啊,我也遇到这样的问题!

牧之 | 园豆:202 (菜鸟二级) | 2013-05-28 09:29

不好意思,好久没有来了。

支持(0) 反对(0) | 园豆:188 (初学一级) | 2015-01-27 17:17
0

我也遇到这问题,请楼主分享解决办法。谢谢!

润物之音 | 园豆:101 (初学一级) | 2015-01-13 10:02

后来在服务端请求了。不要在客户端请求。

支持(0) 反对(0) | 园豆:188 (初学一级) | 2015-01-27 17:17
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册