我有一个运行mvc4的项目,并使用简单的成员资格进行身份验证。我只想允许用户在一个浏览器上登录。要使用户透明,我需要一种方法可以在用户登录时退出任何其他经过身份验证的浏览器。这意味着,如果两个用户试图使用相同的登录,则它们只会互相互动非常不生产。

现在,我已经设置了,只允许用户登录一次,但如果该用户关闭浏览器并移动到另一台计算机,他们将被锁定30分钟,我可以看到这个创建这个创造了一些不必要的支持电话。

我会假设我需要跟踪数据库中的某种标识符,并检查以确保与每个请求相匹配,否则它们会被记录。也许,添加某种cookie。

如果有人对此有优雅的解决方案,我会很感激!

这是我目前使用的是锁定用户只有一个登录:

登录:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
    string sKey = model.UserName;
    string sUser = Convert.ToString(System.Web.HttpContext.Current.Cache[sKey]);

    if (sUser == null || sUser == String.Empty)
    {
        TimeSpan SessTimeOut = new TimeSpan(0, 0, System.Web.HttpContext.Current.Session.Timeout, 0, 0);
        System.Web.HttpContext.Current.Cache.Insert(sKey, sKey, null, DateTime.MaxValue, SessTimeOut, System.Web.Caching.CacheItemPriority.NotRemovable, null);

        Session["user"] = model.UserName;

        if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
        {
            return RedirectToLocal(returnUrl);
        }

        // If we got this far, something failed, redisplay form
        ModelState.AddModelError("", "The user name or password provided is incorrect.");
    }
    else
    {
        ModelState.AddModelError("", "You are already logged in.");
   }

    return View(model);
}
.

global.asax

protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
    if (HttpContext.Current.Session != null)
    {
        if (Session["user"] != (null)) // e.g. this is after an initial logon
        {
            string sKey = (string)Session["user"];
            // replace the last hit with current time
            // Accessing the Cache Item extends the Sliding Expiration automatically
            string sUser = (string)HttpContext.Current.Cache[sKey];
        }
    }
}
.

注销:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
    UserProfile user = db.UserProfiles.SingleOrDefault(s => s.UserName == User.Identity.Name);
    string sKey = user.UserName;
    System.Web.HttpContext.Current.Cache.Remove(sKey);
    WebSecurity.Logout();
    return RedirectToAction("Start", "Home");
}
.

我使用过这个词会话并删除了它。我不是在尝试删除用户的会话,但使用Web安全性使其授权无效。

有帮助吗?

解决方案

这没有内容。您必须自己开发一些方法。你基本上需要两件:

  1. 在跨请求跟踪登录用户的某种方式。这可以像具有用户名列一样简单的表格,您可以使用该表来确定该特定用户名是否已登录。您当然需要与登录/注销同步,您也需要存储用户的会话ID。对于下一块,您需要它:

  2. 从其中存在的任何商店删除会话的某些机制。如果您使用的是SQL会话,这将是最简单的,因为您可以使用匹配ID从表会话表中删除行。没有办法使用ASP.NET直接执行此操作,因此您必须直接查询数据库,使用存储过程等。

  3. 所以,一般想法是当用户登录时,您将在表中记录其用户名和会话ID或其他持久存储的商店。当有人尝试登录时,您将检查该商店是否有关正在尝试的用户名,如果存在,则删除对应于此的会话。下次用户使用该会话尝试访问页面时,他们的会话cookie将不再匹配有效会话,并且他们将被视为他们已被退出。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top