如何注销多个不是当前用户的MembershipUsers?

3

我正在使用MVC2默认项目中的MembershipProvider。

我想能够获取用户列表,注销用户并在需要时销毁他们的会话。我似乎最接近的方法是:

foreach(string userName in UserNames)
{
    MembershipProvider MembershipProvider = new MembershipProvider();
    MembershipUser membershipUser = MembershipProvider.GetUser(userName, true);
    Session.Abandon();
    FormsAuthentication.SignOut();
}

我认为我需要使用与我想要注销的用户相关的会话和/或注销方法,但我不确定它们应该在哪里。
正确的做法是什么?

那样做行不通... Session.Abandon() 只会针对当前的 HttpContext,而不是每个用户的。 - turtlepick
3个回答

2

那样行不通...

Session.Abandon() 只能作用于当前 HttpContext,而不能像你尝试的那样作用于每个用户。 FormsAuthentication.SignOut() 同理。

最好的方法是在 Application_AuthenticateRequest 事件中检查当前用户是否在该数组中,并在那里将其注销:

  protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
            if (User.Identity.IsAuthenticated)
            {
                //add your ckeck here

                 if (Usernames.Contains(User.Identity.Name))
                    {
                       Session.Abandon();
                       FormsAuthentication.SignOut();
                    }
            }       
    }

我能够在硬编码用户名时使其注销用户,但是我不禁觉得这是一个奇怪的放置位置。我需要一些方法在那里加载我想要注销的用户名。这可能意味着每次调用该方法都需要进行数据库调用。 - Sgraffite
我认为这让我感觉很奇怪,因为在这种情况下,你需要等待用户再次访问网站才能强制注销他们的登录。应该有一种方式在服务器端使他们的会话失效,这样他们的 cookie 就无效了。 - Sgraffite
问题在于每个请求都要通过HttpContext,并且它处理的模块之一是“SessionModule”。在那时,您只能读取此请求者的会话。即使进行“打开的会话数量”计数,您也需要自定义逻辑并监视会话事件。 - turtlepick
关于“调用数据库”,每次您都可以将“用户名”作为应用程序变量IList<string>,并始终从此列表中添加/删除帐户,而不是每次都要访问数据库。 - turtlepick

1

我在这个过程中没有使用成员资格提供程序,但基本上是当用户登录时将SessionId、用户名和上一页访问保存在数据库中。然后每个页面都使用当前SessionID获取用户名并执行相关的用户名操作,例如显示当前用户的余额等。如果会话中没有有效的用户,则返回到登录页面。

这使我能够查看用户通过网站的进度,并手动断开任何人,并为每个用户提供单一登录。还有一堆全局.asx页面的清理代码。


我知道如何做,但我真的想知道如何使用MembershipProvider来完成它。谢谢你的建议。 - Sgraffite

0

这与MembershipProvider关系不大,而是与FormsService有关。我的最终解决方案是两个其他答案的混合体。

我最终在Account控制器的LogOn操作中创建了自己的FormsAuthenticationTicket。我为用户的已验证会话生成一个唯一标识符,并将该标识符保存到数据库中。我还将用户的ID添加到auth ticket的UserData部分以进行可靠的查找。默认情况下,auth ticket仅包含用户名。然后,在用户成功登录后,将FormsAuthenticationTicket存储在cookie中。

基本上,所有这些都替换了FormsService.SignIn(model.UserName, model.RememberMe);

我还在Global.asax中添加了public void Application_ReleaseRequestState(object sender, EventArgs args)。我不确定这是否被认为是扩展函数,因为它似乎不是覆盖。在Application_ReleaseRequestState内部,它从cookie获取用户的FormsAuthenticationTicket。然后,它解密auth ticket,并从ticket的UserData部分获取用户的UserID。然后,它询问数据库auth ticket是否仍然有效。如果ticket无效,则将用户的cookie设置为过期。

为了强制用户注销,我可以在数据库中更改他们的身份验证票证到期日期,或者切换他们的身份验证票证的禁用位。无论哪种方式,当Application_ReleaseRequestState询问数据库是否有效时,他们的身份验证票证都将无效。因此,在进行此检查后,他们的Cookie将在用户访问下一页时过期。

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