CurrentPrincipal.Identity.IsAuthenticated is true

2019-09-09 20:40发布

问题:

Refering to sharing cookie in subdomains I implemented jro's answer and it worked for sign in. (sharing the cookie in different sub domains)

However with this change effected the signout process. Please refer to the SignOut and SignIn code I shared below.

The issue is that in the signout process it does a FormsAuthentication.SignOut and then redirect to the sign in controller, but "System.Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated" is set to true even though the FormsAuthentication.SignOut is called in the sign out process.

Code that sets the Forms Authentication 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;
        }

Sign Out

 public ActionResult SignOut()
        {                        

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

                FormsAuthentication.SignOut();

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

SignIn

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

Appreciate any help on this.

回答1:

You have to set the CurrentPrincipal and the user to null in your SignOut method

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

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

        return View();
    }
}

Hope this help.



回答2:

Solved the issue. If you set the domain name manually, you have to set the domain name from the webconfig forms authentication settings. Otherwise it will try to clear cookies from the default domain (in my case subapp1.parent.com), where there is no such cookie since I have manually overridden the cookie domain.

My forms authentication settings was as follows

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

Then I added domain=".parent.com" as the domain and it started working.

Here is how I diagnosed the issue,

I tried following code to manually remove any cookies during sign out,

 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);
            }

Still the issue was there. But I logged (log4net) the cookie.Domain to get details when this happens. Surprisingly the domain was empty, where I was expecting "parent.com". Then I checked the forms-authentication settings and figured out the domain name was not set there.

Hope this will help to save several hours for someone!