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

把我的头撞得有点太长了。如何防止用户在使用 FormsAuthentication 注销后浏览网站页面。登记?我希望这样做:

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

但事实并非如此。如果我直接输入一个 URL,我仍然可以浏览到该页面。我有段时间没用过自动防盗系统了所以我忘了为什么这个不管用了。

144318 次浏览

您发布的代码看起来应该正确地删除表单身份验证标记,因此有可能所涉及的文件夹/页实际上没有受到保护。

是否确认在登录之前无法访问页面?

您能发布您正在使用的 web.config 设置和登录代码吗?

在我看来,您似乎没有在内部正确设置 web.config 授权部分。下面是一个例子。

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

您正在使用 IE 测试/看到这种行为吗?IE 可能正在从缓存中提供这些页面。众所周知,IE 很难刷新它的缓存,所以在很多情况下,即使在你退出之后,输入一个“安全”页面的 URL 会显示之前缓存的内容。

(我见过这种行为,甚至当你以不同的用户登录时,IE 显示“欢迎”栏在你的页面顶部,与老用户的用户名。现在,通常重新加载会更新它,但是如果它是持久的,它仍然可能是一个缓存问题。)

可能是你从一个子域名(sub1.domain.com)登录,然后试图从另一个子域名(www.domain.com)注销。

我一直在为我所有的 Pages 编写一个基类,我遇到了同样的问题。 我有下面这样的代码,但是没有用。通过跟踪,控件从 RedirectToLoginPage ()语句传递到下一行,而不需要重定向。

if (_requiresAuthentication)
{
if (!User.Identity.IsAuthenticated)
FormsAuthentication.RedirectToLoginPage();


// check authorization for restricted pages only
if (_isRestrictedPage) AuthorizePageAndButtons();
}

我发现有两种解决方案。 要么修改 FormsAuthentication.RedirectToLoginPage () ; 要么为

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

或通过添加

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

在第二种情况下,在跟踪时,控件未到达所请求的页。在到达中断点之前,它已经被立即重定向到登录网址。 因此,SignOut ()方法不是问题所在,重定向方法才是问题所在。

我希望这能帮到别人

问候

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

您应该将您的代码更改为:

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名称空间中。

我刚刚遇到了同样的问题,SignOut ()似乎未能正确地删除票据。但只有在特定的情况下,其他一些逻辑会导致重定向。在我删除了第二个重定向(用错误消息替换它)之后,问题就消失了。

问题一定是页面在错误的时间重定向,因此不会触发身份验证。

这里的关键是你说“如果我直接输入一个 URL...”。

默认情况下,在表单身份验证下,浏览器为用户缓存页面。因此,直接从浏览器地址框下拉框中选择一个 URL,或者输入它,可能会从浏览器的缓存中获取页面,而永远不会回到服务器检查身份验证/授权。解决方案是防止在每个页面的 Page _ Load 事件或基页的 OnLoad ()中进行客户端缓存:

Response.Cache.SetCacheability(HttpCacheability.NoCache);

你也可以打电话给:

Response.Cache.SetNoStore();

我以前也有过这样的经历。

这里有一个关于正在发生的事情的类比... 一个新的访问者,Joe,来到站点并通过使用 FormsAuthentication 的登录页面登录。NET 为 Joe 生成一个新的身份,并给他一个 cookie。那块饼干就像房子的钥匙只要乔带着那把钥匙回来他就能打开锁。每个访问者都有一把新钥匙和一把新锁可以使用。

当调用 FormsAuthentication.SignOut()时,系统告诉 Joe 丢失密钥。正常情况下,这是可行的,因为乔已经没有钥匙了,他进不去。

然而,如果乔曾经回来,和 是的丢失的钥匙,他是让回来!

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

我可以接受的方法是在 Session 变量中记住 Joe 的名字。他退出之后,我就放弃治疗所以我就不知道他的名字了。后来,为了检查他是否被允许进入,我只是比较了一下他的身份。当前会话的名称,如果它们不匹配,那么他就不是有效访问者。

简而言之,对于一个网站,不要依赖于 User.Identity.IsAuthenticated也检查您的会话变量!

这对我有用

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

放弃()并销毁 cookie 非常有效。我正在使用 mvc3,看起来如果你进入一个受保护的页面,注销,然后通过浏览器历史记录就会出现问题。没什么大不了的,但还是有点烦人。

尽管如此,尝试在我的网络应用程序中浏览链接是正确的方式。

将其设置为不进行浏览器缓存可能是解决方法。

当我将 认证 > 表格 > 路径属性设置为 Web.config时,这种情况开始发生在我身上。移除了这个问题,一个简单的 FormsAuthentication.SignOut();再次移除了 cookie。

我现在有一个类似的问题,我相信问题在我的情况下,以及原来的海报是因为重定向。默认情况下响应。重定向会导致异常立即冒泡,直到被捕获并立即执行重定向,我猜这会阻止修改后的 cookie 集合传递给客户机。如果修改代码以使用:

Response.Redirect("url", false);

这可以防止异常,并且似乎允许将 cookie 正确地发送回客户端。

我只是在这里尝试了一些建议,当我能够使用浏览器返回按钮时,当我点击菜单选项时,[ ActionResult ]的[ Authorize ]令牌将我送回到登录屏幕。

这是我的注销代码:

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

尽管浏览器上的 back 函数将我带回并显示了安全菜单(我还在做这个工作) ,但是我不能做任何在应用程序中安全的事情。

希望这个能帮上忙

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

X64igor 给出了注销的例子:

  • 您首先需要通过在对注销的响应中传回空 cookie 来实现 清除身份验证 Cookie 和会话 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 gave the example above of how to prevent caching after logout:

  • You need to Invalidate the Cache on the Client Side via the Response.

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

请注意,如果来自 STS 的 wsignoutclean 消息的 URL 与来自 IIS 的应用程序的名称不匹配,WIF 拒绝会告诉浏览器清理 cookie,我指的是 案件敏感。WIF 用绿色的 OK 检查来响应,但是将 没有发送命令删除 Cookie 到浏览器。

所以你需要注意你 url 的大小写敏感性。

例如,ThinkTectureIdentity 服务器将访问 RP 的 URL 保存在一个 cookie 中,但它将所有这些 URL 都设置为小写。WIF 将接收小写的 wsignoutclean 消息,并将其与 IIS 中的应用程序名称进行比较。如果不匹配,则不删除 Cookie,但会向浏览器报告 OK。因此,对于这个 Identity Server,我需要在 web.config 中编写所有 url,在 IIS 中编写所有应用程序名称(小写) ,以避免此类问题。

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

我在这个帖子里试了大部分答案,都没有结果:

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

在这里找到的: http://forums.asp.net/t/1306526.aspx/1

当您按下登录键时,只需尝试发送一个会话变量。 在欢迎页面上,首先检查该会话在页面加载中是否为空,如下所示,还是在 Init Event 中为空:

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

对于 MVC 来说,这对我很有用:

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

经过大量的搜索,最后这个对我有用。我希望它有帮助。

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>

我想添加一些信息来帮助理解这个问题。FormsAuthentication 允许将用户数据存储在 cookie 或 URL 的查询字符串中。您的站点支持的方法可以在 web.config 文件中配置。

根据微软的说法:

SignOut 方法将删除 Forms-Authentication 票证信息 从 cookie 或 URL 如果 Cookie 被支持为 false

与此同时,他们说:

HttpCookieMode 值之一,该值指示 应用程序配置为无 Cookie 表单身份验证 默认值是 UseDeviceProfile

最后,关于 UseDeviceProfile,他们说:

如果 CookieMode 属性设置为 UseDeviceProfile,则 属性的浏览器将返回 true 当前请求支持 cookies 和 cookies 的重定向; 否则,Cookie 支持的属性将返回 false。

根据用户的浏览器,将这些组合在一起,默认配置可能会导致 Cookie 支持为 没错,这意味着 SignOut 方法不会从 Cookie 中清除票据。这似乎与直觉相反,我不知道为什么它是这样工作的——我希望 SignOut 在任何情况下都能真正签出用户。

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

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

根据我的测试,这样做可以让 SignOut 自己工作,代价是你的站点现在需要 cookie 才能正常工作。

对我来说,以下方法是有效的。我认为如果在“ FormsAuthentication”之后出现任何错误。语句,SingOut 不工作。

public ActionResult SignOut()
{
if (Request.IsAuthenticated)
{
FormsAuthentication.SignOut();


return Redirect("~/");
}
return View();
}

这个答案在技术上和科斯罗是一样的。帕克马尼什。我发布这个帖子是为了澄清他的回答和这个帖子上的其他回答有什么不同,以及在什么情况下可以使用这个回答。

一般来说,要清除用户会话,请执行

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

将有效地注销用户。如果在同一个请求中您需要检查 Request.isAuthenticated(例如,在授权过滤器中经常发生的情况) ,那么您将发现

Request.isAuthenticated == true

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

唯一有效的方法就是

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

这实际上设置了 Request.isAuthenticated = false