已删除用户即使在其他浏览器上删除后也已登录

时间:2011-05-05 13:18:36

标签: c# entity-framework asp.net-mvc-3 forms-authentication

var query = from p in AdminModelContext.Users
            where p.UserName == model.UserName && p.Password == encryptPassword 
            && p.IsDeleted == false
                                select p;
            IList<Users> userList = query.ToList();

if (userList.Count() > 0)
{
    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);

    if (CheckUrl(returnUrl))
    {
        return Redirect(returnUrl);
    }

    SetRoleForUser(userList[0].RolesId);
    LoggerService.Info(string.Format("Login Successful for the user : {0}", 
        model.UserName));

    return RedirectToAction("Index", "Home");
}

我使用以下代码登录我的网站。我面临的问题是当我在特定浏览器上与用户登录并同时在不同浏览器上与其他用户登录时,然后我删除该用户(在其他浏览器上登录)。我仍然可以浏览已删除用户登录的页面。

我没有找到一个公平的解决方案来在每个页面上放置身份验证逻辑。我的网站采用MVC模式,并使用基于表单的身份验证。

请建议如何进行登录用户会话验证并实现此目的。

3 个答案:

答案 0 :(得分:1)

到目前为止,答案中没有一个真正承认这个问题。

让我们看一下控制流程:

User A enters log in page, supplies valid credentials
User A is issued Ticket A.

User B enters site, supplies valid credentials.
User B is issued Ticket B.

User B then revokes User A's access CREDENTIALS.

此时Ticket A没有任何反应。因为Ticket独立于凭证。当票证A到期时,他们将被要求出示他们的凭证,但登录失败。

所以你注意到将实际用户踢出你的网站实际上非常困难。正如您所知,唯一的解决方案是在每个请求上都有身份验证逻辑。不幸的是,这真的很重。

在我构建的登录系统中,我通过创建2张票证,1张存储在Forms Auth票证中的票证,持续时间很长,以及存储在HttpRuntime.Cache中的票证,我设置了缓存到期时间为15分钟。

在每个页面请求中,我检查用户是否在缓存中有票证(基于他们的Forms Auth票证信息),此时如果他们没有票证我会进行用户数据刷新并轮询用户数据库。如果用户被暂停或删除,他们将在那时注销。

使用此方法我知道我的网站可以禁用用户,并在15分钟内禁止用户访问该网站。如果我希望它们立即被禁止,我可以循环应用程序配置以清除缓存并强制它发生。

答案 1 :(得分:0)

通常,如果您为Controller或Action定义了[Authorize]属性,则会在每个帖子上检查身份验证。

MembershipProvider中的构建处理所有这些。但似乎您正在使用自己的用户数据库。然后,您必须实现自己的MembershipProviderIPrincipalMembershipUser,并将其添加到您的Web.config中,替换默认值。

您可以在此处找到更多如何实现自己的MembershipProvider:http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx

我的建议是创建一个空的MVC项目,并查看默认的身份验证机制。如果您使用新数据库构建新应用程序,请尝试使用默认身份验证。

您自己的MembershipProvider中的validateUser函数可能如下所示。

public override bool ValidateUser(string username, string password)
{
    bool isValid = false;
    bool isApproved = false;
    string pwd = "";

    using (AdminModelContext db = new AdminModelContext())
    {
        var user = db.Users.FirstOrDefault(u => u.UserName == username);
        if (user != null)
        {
            pwd = user.Password;
            isApproved = user.IsApproved;

            if (CheckPassword(password, pwd))
            {
                if (isApproved)
                {
                    isValid = true;

                    user.LastLoginDate = DateTime.Now;
                    user.LastActivityDate = DateTime.Now;

                    try
                    {
                        db.SubmitChanges();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex);
                    }
                }
            }
            else
            {
                UpdateFailureCount(username, "password");
            }
        }
    }

    return isValid;
}

答案 2 :(得分:0)

我现在看到了问题。我不知道它在MVC中如何工作,但通过使用Authenticate_Request,您可以验证用户是否仍然有效。业务逻辑还可以仔细检查用户是否仍然有效。但据我所知,没有办法迭代所有打开的会话并杀死所有开放的会话,即使在这种情况下,应该在Session_Start事件上对授权cookie进行双重检查。 另一个选项是在应用程序上添加全局invalidated_users列表,然后针对无效列表检查该用户。此列表应仅包含在应用程序重新启动后失效的用户。

阅读所有用户会话的链接:

http://weblogs.asp.net/imranbaloch/archive/2010/04/05/reading-all-users-session.aspx