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

26

我的应用程序允许管理员暂停/恢复用户帐户。我使用以下代码实现:

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

以上代码可以成功暂停用户,但是它没有撤销用户的会话。因此,只要用户的会话 cookie 仍然存在,被暂停的用户仍然可以访问应用程序。请问有什么解决方法吗?

4个回答

27

无法从“外部”结束会话。您需要在每个页面加载时检查数据库,如果帐户已被禁用,则注销。您也可以使用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"])); 中,你的意思是我们应该用获取用户的任何方法来替换这一行代码吗?比如从数据库中调用? - FarFigNewton
@guanome 是的,没错。上面的代码示例假设您将用户ID存储在会话中。这行代码的目的是使用存储在会话中的值从数据库中检索用户(例如他们的ID),以便您可以检查他们的状态。 - Mun

6

如果使用表单身份验证:

FormsAuthentication.SignOut();

7
他们想结束另一个会话而不是当前用户的会话,因此这不合适。 - David Burton
Request.GetOwinContext().Authentication.SignOut(); - Pam Nelligan

5
当您注销用户时,覆盖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();

2
在一些常见的页面上,检查账户是否有效,如果已被撤销,则调用Session.Abandon()
编辑(刚注意到这还没解决)。
我知道这很有效,因为我自己也这么做了。
在主页面上检查账户状态。这意味着每次导航时都有机会让他们退出登录。
(最终)编辑
不要把它看作“我正在终止他们的会话”,而是把它看作“他们的会话自行终止”。

2
这只是针对当前用户会话的吗?我想要放弃另一个用户的会话... 类似于 Session(user).Abandon。 - Testing123
1
@Testing123 egrunin 的意思是每个用户都会检查自己的帐户是否无效,如果是,则应用程序将删除他们的 cookie。 - FarFigNewton
因为你需要使用FormsAuthentication.SignOut(),所以被踩了。 - Juan
关于 FormsAuthentication.SignOut():正如 @David Burton 在另一条评论中指出的那样,“他们想要结束另一个会话而不是当前用户的会话,因此这并不合适”。 - egrunin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接