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();
HttpCookie
在System.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。