CurrentPrincipal.Identity.IsAuthenticated 即使在注销后手动设置 FormsAuth cookie 域时也是如此

CurrentPrincipal.Identity.IsAuthenticated is true even after signout when FormsAuth cookie domain set manually

参考 sharing cookie in subdomains 我实现了 jro 的答案并且它用于登录。(在不同的子域中共享 cookie)

但是,此更改影响了注销过程。请参考我在下面分享的 SignOut 和 SignIn 代码。

问题是在注销过程中它执行 FormsAuthentication.SignOut 然后重定向到登录控制器,但是 "System.Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated" 设置为 true 即使 FormsAuthentication.SignOut 被调用在注销过程中。

设置表单身份验证 Cookie 的代码

 public static HttpCookie GetAuthenticationCookie(CookieData cookieData)
        {
            string userData = PrepareCookieContentFromCookieData(cookieData); //Get a string with User data

            AuthenticationSection section = WebConfigurationManager.GetWebApplicationSection("system.web/authentication") as AuthenticationSection;

            TimeSpan ts = section.Forms.Timeout;
            int timeout = (ts.Minutes != 0) ? timeout = ts.Minutes : 1;

            bool isPersistent = Convert.ToBoolean(HttpContext.Current.Request.Form["isPersistent"] ?? "False");

            if (isPersistent) timeout = 30 * 24 * 60;

            //ticket object is formed based on the above details set. Evry page afer login will use this ticket to get base user data
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, cookieData.userName, DateTime.Now,
                DateTime.Now.AddMinutes(timeout), isPersistent, userData, FormsAuthentication.FormsCookiePath);

            // to encrypt the ticket 
            string encryptedCookieString = FormsAuthentication.Encrypt(ticket);

            // setting the ticket to the cookie.
            var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedCookieString);
            cookie.HttpOnly = true;
            cookie.Domain = "parent.com";
            if (isPersistent)
                cookie.Expires = DateTime.Now.AddYears(1);

            return cookie;
        }

退出

 public ActionResult SignOut()
        {                        

                if (HttpContext != null && HttpContext.Session != null)
                {                      
                    HttpContext.Session.Abandon();
                }    

                FormsAuthentication.SignOut();

            } 
            return RedirectToAction("SignIn", "User");    
        }

登录

 public ActionResult SignIn(string CompanyCode)
        {           
           //Check if logged in
            if (System.Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated)
            {
                //return to a specific page
            }
        }

感谢任何帮助。

您必须在 SignOut 方法中将 CurrentPrincipal 和用户设置为 null

public class LogOffController : Controller
{
    public ActionResult Index()
    {
        FormsAuthentication.SignOut();

        HttpContext.User = null;
        Thread.CurrentPrincipal = null;

        return View();
    }
}

希望对您有所帮助。

问题已解决。如果手动设置域名,则必须从 webconfig 表单身份验证设置中设置域名。否则它将尝试从默认域(在我的例子中 subapp1.parent.com)中清除 cookie,因为我已经手动覆盖了 cookie 域,所以没有这样的 cookie。

我的表单验证设置如下

<forms cookieless="UseCookies" defaultUrl="~/Applications" loginUrl="~/user/signin"  name="FormAuthentication" path="/"/>

然后我将 domain=".parent.com" 添加为域,它开始工作了。

这是我诊断问题的方式,

我尝试使用以下代码在注销期间手动删除所有 cookie,

 var cookie = HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName];

            if (cookie != null)
            {
                Logger.Log.InfoFormat("Cookies found. Domain:{0} Name:{1}", cookie.Domain, cookie.Name);

                cookie.Expires = DateTime.Now.AddYears(-1);
                Response.Cookies.Add(cookie);
            }

问题依然存在。但是我记录了 (log4net) cookie.Domain 以获取发生这种情况时的详细信息。令人惊讶的是,该域是空的,而我期望 "parent.com"。然后我检查了forms-authentication设置,发现那里没有设置域名。

希望这有助于为某人节省几个小时!