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设置,发现那里没有设置域名。
希望这有助于为某人节省几个小时!
参考 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设置,发现那里没有设置域名。
希望这有助于为某人节省几个小时!