C# Page.User.Identity.IsAuthenticated在FormsAuthentication.SignOut()之后仍然为真

C# Page.User.Identity.IsAuthenticated在FormsAuthentication.SignOut()之后仍然为真,c#,asp.net,forms-authentication,C#,Asp.net,Forms Authentication,我有一个页面,当您按“注销”时,它将重定向到login.aspx页面,该页面有一个page\u Load方法,该方法调用FormsAuthentication.SignOut() 母版页在屏幕右上角显示“注销”链接,并在page.User.Identity.IsAuthenticated为true的条件下显示该链接。但是,在逐步完成代码之后,此注销方法不会自动将IsAuthenticated设置为false,这很烦人,有什么想法吗?我记得有一个类似的问题,我想我通过在注销时使表单身份验证cook

我有一个页面,当您按“注销”时,它将重定向到
login.aspx
页面,该页面有一个
page\u Load
方法,该方法调用
FormsAuthentication.SignOut()


母版页在屏幕右上角显示“注销”链接,并在
page.User.Identity.IsAuthenticated
true
的条件下显示该链接。但是,在逐步完成代码之后,此注销方法不会自动将
IsAuthenticated
设置为
false
,这很烦人,有什么想法吗?

我记得有一个类似的问题,我想我通过在注销时使表单身份验证cookie过期来解决它:

FormsAuthentication.SignOut();
Response.Cookies[FormsAuthentication.FormsCookieName].Expires = DateTime.Now.AddYears(-1);

在login.aspx页面的加载方法中:

if (!this.IsPostBack)
{
    if (HttpContext.Current.User.Identity.IsAuthenticated)
    {
        FormsAuthentication.SignOut();
        Response.Redirect(Request.RawUrl);
    }
}
更新 我得到的评论是,我的答案对很多人不起作用。我在2011年撕碎了我的耳朵后写下了这个答案。所以我很确定它解决了这个问题

我开始研究这个6年前的问题,我认为这可能是删除cookies的正确方法,即再次创建cookies,但过期


这对我有用

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

每个请求只对一个人进行一次身份验证。一旦ASP.NET确定它们是否经过身份验证,则该请求的其余部分不会更改


例如,当有人登录时。当您设置表单身份验证cookie以指示它们已登录时,如果您检查它们是否在同一请求上经过身份验证,它将返回
false
,但在下一个请求上,它将返回
true
。当你注销某人时也会发生同样的情况。在该请求期间,它们仍然经过身份验证,但在下一次请求中,它们将不再经过身份验证。因此,如果用户单击链接注销,您应该将其注销,然后重定向到登录页面。

page.user.Identity.IsAuthenticated
页面获取其值。user
(显然)很遗憾,它是只读的,在调用
FormsAuthentication.SignOut()时不会更新

幸运的是
页面。用户
从上下文中提取其值。用户
可以修改:

// HttpContext.Current.User.Identity.IsAuthenticated == true;

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

// now HttpContext.Current.User.Identity.IsAuthenticated == false
// and Page.User.Identity.IsAuthenticated == false

当您注销当前用户并希望在不重定向的情况下使用实际页面进行响应时,这非常有用。您可以在同一页面请求中的需要位置检查
IsAuthenticated

为什么要在login.aspx中执行注销代码

将此代码放入例如logout.aspx:

FormsAuthentication.SignOut()
Session.Abandon()
FormsAuthentication.RedirectToLoginPage()
HttpContext.Current.ApplicationInstance.CompleteRequest()
return
在login.aspx中,IsAuthenticated将为false。
登录和注销代码现在是分开的:单一责任。

在我的一个应用程序中,当我使用凭据登录时,导航到应用程序中的不同表单,然后我复制了一个导航表单url,然后从应用程序中注销。在“搜索”选项卡中,我粘贴了浏览器导航到应用程序中特定表单的url,而无需登录。 检查表单身份验证为
page.User.Identity.IsAuthenticated时
即使在注销时也会变为true。原因是在注销时清除会话时我添加了

Response.Cookies[FormsAuthentication.FormsCookieName].Expires = DateTime.Now.AddYears(-1);

有了这一点,我就不会再遇到这个问题了,当我们在应用程序中导航到不同的表单而不登录时,
page.User.Identity.IsAuthenticated
的标志将变为false。

我的理解是,你应该检查auth cookie的存在,而不是这个标志?我该怎么做?我认为在FormsAuthentication.SignOut()之后cookie仍然存在。可能的重复问题请记住:Authenticated=“System know your”Authenticated=“System know your”Authorized=“System know your被允许做什么”。也就是说:LogOut=“授权无效”。。。。但“系统仍然知道你是谁”的回答稍微有点延迟,但从记忆中我认为这与问题最终解决的方式类似!对你来说有点延迟,但我只是遇到了同样的问题,发现你的问题很好,但没有一个合适的答案。我希望它能帮助别人。这对我有帮助!谢谢你,玛特+1:)与MVC4完美结合,只做了一个小改动:
HttpContext.User=new-GenericPrincipal(new-genericentity(string.Empty),null)我还选择了HttpContext.Current.User=null;如果您正在检查空“用户”,则此功能非常有用。在响应时删除cookie不会导致删除它。Cookie需要过期,这是删除已设置的Cookie的唯一方法。此外,您不希望仅在授权后“过期”所有Cookiecookies@Mike这个解决方案怎么样?是的,这个例子是有效的,因为这个人检查了响应上的所有cookie,并将它们更改为已过期,然后在响应中发送这些过期的cookie,当客户端浏览器收到它们时,它会自动删除它们,因为它们已过期。
HttpContext.Current.Request.Cookies.Clear()行正在修改当前的请求对象,而不是响应-这意味着当代码继续处理该请求时,没有cookie可供其使用。但是,响应仍然包含所有cookie,但已过期。您的示例不会更改cookie的过期时间。。。我必须承认,我不确定是否必须以这种方式删除
HttpOnly
cookies。它们可能只需要被移除。