以编程方式注销 ASP.NET 用户

Posted

技术标签:

【中文标题】以编程方式注销 ASP.NET 用户【英文标题】:Programmatically logout an ASP.NET user 【发布时间】:2011-03-07 03:18:20 【问题描述】:

我的应用允许管理员暂停/取消暂停用户帐户。我使用以下代码执行此操作:

MembershipUser user = Membership.GetUser(Guid.Parse(userId));
user.IsApproved = false;
Membership.UpdateUser(user);

上述方法可以很好地暂停用户,但不会撤销他们的会话。因此,只要会话 cookie 保留,暂停的用户就可以继续访问应用程序。任何修复/

【问题讨论】:

【参考方案1】:

无法从会话“外部”放弃会话。您必须在每个页面加载时检查数据库,如果帐户已被禁用,则退出。您也可以使用 HttpModule 来实现这一点,这会使事情变得更简洁。

例如:

public class UserCheckModule : IHttpModule

    public void Init(HttpApplication context)
    
        context.PreRequestHandlerExecute += new EventHandler(OnPreRequestHandlerExecute);
    

    public void Dispose() 

    private void OnPreRequestHandlerExecute(object sender, EventArgs e)
    
        // Get the user (though the method below is probably incorrect)
        // The basic idea is to get the user record using a user key
        // stored in the session (such as the user id).
        MembershipUser user = Membership.GetUser(Guid.Parse(HttpContext.Current.Session["guid"]));

        // Ensure user is valid
        if (!user.IsApproved)
        
            HttpContext.Current.Session.Abandon();
            FormsAuthentication.SignOut();
            HttpContext.Current.Response.Redirect("~/Login.aspx?AccountDisabled");
        
    

这不是一个完整的示例,需要调整使用存储在会话中的密钥检索用户的方法,但这应该可以帮助您入门。这将涉及在每次页面加载时进行额外的数据库检查,以检查用户帐户是否仍处于活动状态,但没有其他方法可以检查此信息。

【讨论】:

MembershipUser user = Membership.GetUser(Guid.Parse(HttpContext.Current.Session["guid"])); 行上,你的意思是我们应该用我们用来获取用户的任何方法替换这一行吗?比如调用数据库? @guanome 没错,是的。上面的代码示例假定您将用户 ID 存储在会话中。这行代码的目的是使用存储在会话中的值从数据库中检索用户(如他们的 ID),以便您检查他们的状态。【参考方案2】:

如果使用表单身份验证:

FormsAuthentication.SignOut();

【讨论】:

他们想要结束另一个会话而不是当前用户的会话,所以这不合适 Request.GetOwinContext().Authentication.SignOut();【参考方案3】:

当您注销用户时,覆盖FormsAuthenticationTicket 也是一个好主意。

HttpContext context = HttpContext.Current;

//overwrite the authentication cookie
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, context.User.Identity.Name, DateTime.Now, DateTime.Now.AddDays(-1), false, Guid.NewGuid().ToString());
string encrypted_ticket = FormsAuthentication.Encrypt(ticket);

HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted_ticket);
cookie.Expires = ticket.Expiration;
context.Response.Cookies.Add(cookie);

//clear all the sessions
context.Session.Abandon();

//sign out and go to the login page
FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();

【讨论】:

【参考方案4】:

在一些常用页面上,检查帐户是否有效,如果已被撤销,请致电Session.Abandon()

编辑(刚刚注意到它仍然处于打开状态。)

我知道这行得通,因为我这样做了。

在主页上,检查帐户状态。这意味着每次导航您都有机会将其注销。

(最终)编辑

不要将其视为“我正在终止他们的会话”,将其视为“他们的会话自行终止”。

【讨论】:

这不只是针对当前用户的会话吗?我想放弃另一个用户的会话...类似 Session(user).Abandon. @Testing123 egrunin 意味着每个用户都会检查他们自己的帐户是否无效,如果是,则应用程序将删除他们的 cookie。 投反对票,因为您需要 FormsAuthentication.SignOut(); 回复:FormsAuthentication.SignOut():正如@David Burton 在另一条评论中指出的那样,“他们想要结束另一个会话而不是当前用户的会话,所以这不合适”

以上是关于以编程方式注销 ASP.NET 用户的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式将用户控件加载到占位符 (asp.net)

用户注销时数据库连接需要时间吗?或从asp.net问题注销

如何让任何视图知道用户角色(ASP.NET MVC 身份)已更改,以强制任何用户在浏览时注销?

使用浏览器后退按钮进行 ASP.NET 身份验证登录和注销

在 ASP.NET 中注销时如何杀死用户的会话

ASP.NET Identity 注销另一个用户