FormsAuthentication.SignOut()不会将用户注销

把我的脑袋撞得这么久, 如何防止用户在使用FormsAuthentication.SignOut登出后浏览网站的页面? 我希望这样做:

FormsAuthentication.SignOut(); Session.Abandon(); FormsAuthentication.RedirectToLoginPage(); 

但事实并非如此。 如果我直接inputurl,我仍然可以浏览到网页。 我有一段时间没有使用自己的安全性,所以我忘了为什么这不起作用。

用户仍然可以浏览您的网站,因为当您调用FormsAuthentication.SignOut()时cookie不会被清除,并且每个新的请求都被authentication。 在MS文件中说,cookie将被清除,但他们不,错误? 与Session.Abandon()完全一样,cookie仍然存在。

你应该改变你的代码:

 FormsAuthentication.SignOut(); Session.Abandon(); // clear authentication cookie HttpCookie cookie1 = new HttpCookie(FormsAuthentication.FormsCookieName, ""); cookie1.Expires = DateTime.Now.AddYears(-1); Response.Cookies.Add(cookie1); // clear session cookie (not necessary for your current problem but i would recommend you do it anyway) SessionStateSection sessionStateSection = (SessionStateSection)WebConfigurationManager.GetSection("system.web/sessionState"); HttpCookie cookie2 = new HttpCookie(sessionStateSection.CookieName, ""); cookie2.Expires = DateTime.Now.AddYears(-1); Response.Cookies.Add(cookie2); FormsAuthentication.RedirectToLoginPage(); 

HttpCookieSystem.Web名称空间中。 MSDN参考 。

听起来像你没有你的web.config授权部分内设置正确。 看下面的例子。

 <authentication mode="Forms"> <forms name="MyCookie" loginUrl="Login.aspx" protection="All" timeout="90" slidingExpiration="true"></forms> </authentication> <authorization> <deny users="?" /> </authorization> 

使用x64igor和Phil Haselden的上述两个post解决了这个问题:

1. x64igor举了一个例子来做注销:

  • 您首先需要通过将响应中的空cookie传回到注销来清除身份validationCookie和会话Cookie

     public ActionResult LogOff() { FormsAuthentication.SignOut(); Session.Clear(); // This may not be needed -- but can't hurt Session.Abandon(); // Clear authentication cookie HttpCookie rFormsCookie = new HttpCookie( FormsAuthentication.FormsCookieName, "" ); rFormsCookie.Expires = DateTime.Now.AddYears( -1 ); Response.Cookies.Add( rFormsCookie ); // Clear session cookie HttpCookie rSessionCookie = new HttpCookie( "ASP.NET_SessionId", "" ); rSessionCookie.Expires = DateTime.Now.AddYears( -1 ); Response.Cookies.Add( rSessionCookie ); 

2. Phil Haselden给出了上面的例子,说明注销后如何防止caching:

  • 您需要通过响应使客户端上的caching失效

      // Invalidate the Cache on the Client Side Response.Cache.SetCacheability( HttpCacheability.NoCache ); Response.Cache.SetNoStore(); // Redirect to the Home Page (that should be intercepted and redirected to the Login Page first) return RedirectToAction( "Index", "Home" ); } 

这里的关键是你说“如果我直接input一个URL …”。

默认情况下,表单身份validation浏览器为用户caching页面。 因此,直接从浏览器地址框下拉菜单中select一个URL,或者input它,可以从浏览器的caching中获取页面,并且不会返回到服务器来检查authentication/授权。 解决方法是在每个页面的Page_Load事件中,或在基本页面的OnLoad()中防止客户端caching:

 Response.Cache.SetCacheability(HttpCacheability.NoCache); 

你也可以打电话给:

 Response.Cache.SetNoStore(); 

我之前也一直在努力。

下面是一个类似于正在发生的事情…一个新的访问者Joe来到该站点并使用FormsAuthentication通过login页面login。 ASP.NET为Joe生成一个新的身份,并给他一个cookie。 那cookies就像房子的钥匙,只要乔带着钥匙回来,他就可以打开锁。 每个访问者都有一个新的密钥和一个新的锁使用。

当调用FormsAuthentication.SignOut() ,系统告诉Joe丢失密钥。 通常情况下,这是有效的,因为乔不再有钥匙,他不能进入。

但是,如果乔回来了,而且失去了钥匙,他就会被放回去!

据我所知,没有办法告诉ASP.NET改变门上的锁!

我可以忍受的方式是在Sessionvariables中记住Joe的名字。 当他注销时,我放弃了Session,所以我不再有他的名字了。 之后,为了检查他是否被允许进入,我只是将他的Identity.Name与当前会话的名称进行比较,如果他们不匹配,他就不是有效的访问者。

总之,对于一个网站,不要依赖User.Identity.IsAuthenticated而不检查你的会话variables!

这对我有用

 public virtual ActionResult LogOff() { FormsAuthentication.SignOut(); foreach (var cookie in Request.Cookies.AllKeys) { Request.Cookies.Remove(cookie); } foreach (var cookie in Response.Cookies.AllKeys) { Response.Cookies.Remove(cookie); } return RedirectToAction(MVC.Home.Index()); } 

经过大量的search终于这个为我工作。 我希望它有帮助。

 public ActionResult LogOff() { AuthenticationManager.SignOut(); HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty), null); return RedirectToAction("Index", "Home"); } <li class="page-scroll">@Html.ActionLink("Log off", "LogOff", "Account")</li> 

您发布的代码看起来应该正确地移除表单身份validation令牌,因此有可能文件夹/页面实际上不受保护。

您是否确认login前无法访问这些页面?

你能发布你正在使用的web.config设置和login代码吗?

我一直在为我所有的页面写一个基类,并且遇到同样的问题。 我有像下面的代码,它没有工作。 通过跟踪,控制从RedirectToLoginPage()语句传递到下一行而不被redirect。

 if (_requiresAuthentication) { if (!User.Identity.IsAuthenticated) FormsAuthentication.RedirectToLoginPage(); // check authorization for restricted pages only if (_isRestrictedPage) AuthorizePageAndButtons(); } 

我发现有两个解决scheme。 要么修改FormsAuthentication.RedirectToLoginPage(); 成为

 if (!User.Identity.IsAuthenticated) Response.Redirect(FormsAuthentication.LoginUrl); 

或者通过添加来修改web.config

 <authorization> <deny users="?" /> </authorization> 

在第二种情况下,在追踪时,控制没有到达请求的页面。 它已经被立即redirect到loginurl之前点击中断点。 因此,SignOut()方法不是问题,redirect方法就是这个问题。

我希望可以帮助别人

问候

我只是在这里尝试了一些build议,而当我能够使用浏览器后退button时,当我点击一个菜单选项时,[ActionResult]的[Authorize]标记将我发回到login屏幕。

这是我的退出代码:

  FormsAuthentication.SignOut(); Response.Cookies.Remove(FormsAuthentication.FormsCookieName); Response.Cache.SetExpires(DateTime.Now.AddSeconds(-1)); HttpCookie cookie = HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName]; if (cookie != null) { cookie.Expires = DateTime.Now.AddDays(-1); Response.Cookies.Add(cookie); } 

虽然浏览器的后台function把我带回来,并显示安全的菜单(我仍然在这个工作),我无法做任何在应用程序中的安全。

希望这可以帮助

我已经在这个线程中尝试了大多数的答案,没有运气。 结束了这个:

 protected void btnLogout_Click(object sender, EventArgs e) { FormsAuthentication.Initialize(); var fat = new FormsAuthenticationTicket(1, "", DateTime.Now, DateTime.Now.AddMinutes(-30), false, string.Empty, FormsAuthentication.FormsCookiePath); Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(fat))); FormsAuthentication.RedirectToLoginPage(); } 

在这里find它: http : //forums.asp.net/t/1306526.aspx/1

这个答案在技术上与Khosro.Pakmanesh相同。 我发布它来澄清他的答案不同于这个线程上的其他答案,以及在哪个用例可以使用。

一般来说要清除一个用户会话,这样做

 HttpContext.Session.Abandon(); FormsAuthentication.SignOut(); 

将有效地注销用户。 但是 ,如果在相同的请求中您需要检查Request.isAuthenticated (例如,可能经常发生在授权filter中),那么您会发现

 Request.isAuthenticated == true 

甚至在你做了HttpContext.Session.Abandon()FormsAuthentication.SignOut()

唯一有用的是做

 AuthenticationManager.SignOut(); HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty), null); 

这有效地设置了Request.isAuthenticated = false

当我在Web.config设置身份validation>窗体>path属性时,发生这种情况。 删除那个固定的问题,和一个简单的FormsAuthentication.SignOut(); 再次删除了cookie。

可能是您从一个子域(sub1.domain.com)login,然后尝试从另一个子域(www.domain.com)注销。

我刚刚遇到了同样的问题,SignOut()似乎无法正确删除票证。 但只有在某个特定的情况下,其他逻辑才会导致redirect。 我删除了第二个redirect(用一个错误信息replace它)之后,问题就消失了。

问题一定是页面在错误的时间redirect,因此不能触发authentication。

我现在有类似的问题,我相信我的情况以及原来的海报问题是由于redirect。 默认情况下,一个Response.Redirect会导致一个exception立即冒出来,直到被捕获,并立即执行redirect,我猜测这是阻止修改的cookie集合被传递到客户端。 如果你修改你的代码来使用:

 Response.Redirect("url", false); 

这防止了exception,似乎允许cookie被正确地发回给客户端。

只要尝试在login时发送会话variables。在欢迎页面上,首先在页面加载或Init事件中检查该会话是否为空,如下所示:

 if(Session["UserID"] == null || Session["UserID"] == "") { Response.Redirect("Login.aspx"); } 

你使用IEtesting/看到这种行为? IE可能会从caching中提供这些页面。 很难让IE浏览器刷新caching,所以很多时候,即使你注销了,input一个“安全”页面的URL也会显示caching的内容。

(即使您以其他用户身份login,我也看到了这种行为,IE在页面顶部显示“欢迎”栏,使用旧用户的用户名。现在,通常重新加载会更新它,但是如果它是持久的,它可能仍然是一个caching问题。)

做Session.abandon()并销毁cookie的作品相当不错。 我正在使用mvc3,看起来像是如果你去一个受保护的页面,注销,并通过您的浏览器历史logging发生问题。 没有什么大不了,但还是有点烦人。

试图通过我的networking应用程序的链接工程正确的方式。

设置它不做浏览器caching可能是要走的路。

对于MVC这适用于我:

  public ActionResult LogOff() { FormsAuthentication.SignOut(); return Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name, true)); } 

我想添加一些信息来帮助理解问题。 表单身份validation允许将用户数据存储在Cookie中或URL的查询string中。 您的站点支持的方法可以在web.config文件中进行configuration。

据微软称 :

如果CookiesSupported为false,则 SignOut方法将从Cookie或URL中删除表单身份validation票据信息。

同时, 他们说 :

其中一个HttpCookieMode值指示应用程序是否configuration了无Cookie表单身份validation。 默认是UseDeviceProfile

最后,关于UseDeviceProfile, 他们说 :

如果CookieMode属性设置为UseDeviceProfile,则CookieSupported属性将返回true,如果 当前请求 的浏览器 同时支持cookie和使用cookieredirect ; 否则,CookiesSupported属性将返回false。

根据用户浏览器的不同,将所有内容拼凑在一起,默认configuration可能导致CookiesSupported为 ,这意味着SignOut方法不会从Cookie中清除票据。 这似乎是反直觉的,我不知道为什么这样工作 – 我希望SignOut在任何情况下实际签署用户。

使SignOut自行工作的一种方法是在web.config文件中将cookie模式更改为“UseCookies”(即需要cookie):

 <authentication mode="Forms"> <forms loginUrl="~/Account/SignIn" cookieless="UseCookies"/> </authentication> 

根据我的testing,这样做使得SignOut自己的工作,以您的网站的成本现在要求cookie正常工作。

对我来说,以下的方法是有效的。 我认为如果在“FormsAuthentication.SignOut()”语句之后有任何错误,SingOut不起作用。

 public ActionResult SignOut() { if (Request.IsAuthenticated) { FormsAuthentication.SignOut(); return Redirect("~/"); } return View(); } 

请注意,如果来自STS的wsignoutcleanup消息与来自IIS的应用程序的名称不匹配,则WIF 拒绝通知浏览器清除cookie,我的意思是CASE SENSITIVE 。 WIF响应绿色OK检查,但不会发送命令删除cookie到浏览器。

所以,你需要注意你的url的区分大小写。

例如,ThinkTecture Identity Server将访问RP的URL保存在一个cookie中,但是它使得所有这些小写都是小写的。 WIF将以小写forms接收wsignoutcleanup消息,并将其与IIS中的应用程序名称进行比较。 如果不匹配,则不会删除cookie,但会向浏览器报告确定。 所以,对于这个身份服务器,我需要在web.config中写所有的URL,而在IIS中写所有的应用程序的名字,以避免这样的问题。

如果您的应用程序在STS的子域之外,也不要忘记在浏览器中允许使用第三方cookie,否则,即使WIF告诉他这些cookie,浏览器也不会删除cookie。