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

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

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

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

【问题讨论】:

    标签: c# asp.net login


    【解决方案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 在另一条评论中指出的那样,“他们想要结束另一个会话而不是当前用户的会话,所以这不合适”
      猜你喜欢
      • 2012-06-15
      • 2012-01-27
      • 2017-01-15
      • 1970-01-01
      • 2012-01-10
      • 2019-01-02
      • 1970-01-01
      • 2014-04-17
      • 1970-01-01
      相关资源
      最近更新 更多