删除在 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"。
有什么想法、建议吗?
首先,没有。无法在另一个会话中访问 cookie,因为它们只在 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);
...
我有一个用 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"。
有什么想法、建议吗?
首先,没有。无法在另一个会话中访问 cookie,因为它们只在 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);
...