删除在 ASP.NET MVC 中验证的用户

Drop user authenticated in ASP.NET MVC

我有一个用 ASP.NET MVC 4 开发的网络系统。

我们有一个用户管理,允许用户 edit/delete 其他用户。 关于删除功能,目前我只对数据库执行 delete

这是我的 login controller/method:

[HttpPost]
public ActionResult Login(LoginViewModel loginViewModel)
{
    if (_loginService == null)
        _loginService = new LoginService();

    var result = _loginService.Login(loginViewModel.User, loginViewModel.Password);
    if (!result.Error)
    {
        var userData = JsonConvert.SerializeObject(result.User);
        FormsAuthentication.SetAuthCookie(result.User.Id, false);
        var ticket = new FormsAuthenticationTicket(1, result.Id, DateTime.Now, DateTime.Now.AddMinutes(9999), true, userData, FormsAuthentication.FormsCookiePath);
        var encryptedCookie = FormsAuthentication.Encrypt(ticket);
        var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedCookie) { Expires = DateTime.Now.AddHours(14) };

        Response.Cookies.Add(cookie);
    }
    return new JsonResult
    {
        Data = result
    };
}

我在客户端用 javascript 处理 return。现在一切正常。

对于必须验证用户身份的每个控制器,我都有 [Authorize] 属性。

假设我刚刚使用用户 ABC 登录。只要 ABC cookie 还活着,他就可以正常导航。问题是当某些用户(比如说 ZXC)删除用户 ABC 时,他仍然可以正常导航,直到 cookie 过期。

有没有办法在 ZXC 从数据库中删除他时删除 IIS 上的 ABC 会话? 我不知道..强制 cookie 过期。我只是不想为导航中完成的每个操作实施咨询,以检查用户是否仍在数据库中 "alive"。

有什么想法、建议吗?

首先,没有。无法在另一个会话中访问 c​​ookie,因为它们只在 request/response 的生命周期内存在。但是,您可以存储所有当前经过身份验证的用户的静态 List 并以这种方式使它们无效。

这有点问题,因为在应用程序池回收的情况下 - 所有用户都将 'logged out'。如果这对您来说不是问题(即应用程序池在凌晨 2 点回收并且它适用于凌晨 2 点不运行的业务系统)那么您可以试试这个...

提供的代码未经测试

来源:https://msdn.microsoft.com/en-us/library/system.web.security.formsauthenticationmodule.authenticate

编辑:
我没有从请求中删除 cookie 并在响应中使其过期。

在Global.asax

private static List<string> _authenticatedUsers = new List<string>();

public static AuthenticateUser (MyApplicationUser user)
{
    if(!_authenticatedUsers.ContainsKey(user.Username))
    {
        _authenticatedUsers.Add(user.Username);
    }
}

public static DeauthenticateUser (MyApplicationUser user)
{
    if(_authenticatedUsers.ContainsKey(user.Username))
    {
        _authenticatedUsers.Remove(user.Username);
    }
}

public void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs args)
{
  if (FormsAuthentication.CookiesSupported)
  {
    if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
    {
      try
      {
        FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(
          Request.Cookies[FormsAuthentication.FormsCookieName].Value);

        MyApplicationUser user = JsonConvert.DeserializeObject(ticket.UserData);

        if(user == null || !_authenticatedUsers.Any(u => u == user.Username))
        { 
            // this invalidates the user
            args.User = null;
            Request.Cookies.Remove(FormsAuthentication.FormsCookieName);
            HttpCookie myCookie = new HttpCookie(FormsAuthentication.FormsCookieName);
            DateTime now = DateTime.Now;

            myCookie.Value = "a";
            myCookie.Expires = now.AddHours(-1);

            Response.Cookies.Add(myCookie);
            Response.Redirect(FormsAuthentication.LoginUrl);
            Resonpse.End();
        }
      }
      catch (Exception e)
      {
        // Decrypt method failed.
        // this invalidates the user
        args.User = null;
        Request.Cookies.Remove(FormsAuthentication.FormsCookieName);
        HttpCookie myCookie = new HttpCookie(FormsAuthentication.FormsCookieName);
        DateTime now = DateTime.Now;

        myCookie.Value = "a";
        myCookie.Expires = now.AddHours(-1);

        Response.Cookies.Add(myCookie);
        Response.Redirect(FormsAuthentication.LoginUrl);
        Resonpse.End();
      }
    }
  }
  else
  {
    throw new HttpException("Cookieless Forms Authentication is not " +
                            "supported for this application.");
  }
}

在您的登录操作中

public ActionResult Login(LoginViewModel loginViewModel)
{
    ...

    if (!result.Error)
    {
        ...
        MvcApplication.AuthenticateUser(result.User);
        ...
    }
    ...
}

在您的注销操作中

public ActionResult Logout(...)
{
    ...
    MvcApplication.DeauthenticateUser(user);
    ...
}

在你的删除方法中

...
MvcApplication.DeauthenticateUser(user);
...