使用自定义 ActionFilterAttribute 在 MVC 5 中注销用户
Posted
技术标签:
【中文标题】使用自定义 ActionFilterAttribute 在 MVC 5 中注销用户【英文标题】:Log Out a User in MVC 5 Using a Custom ActionFilterAttribute 【发布时间】:2015-01-04 12:10:37 【问题描述】:我有一个自定义的 ActionFilterAttribute,它可以确保 Session 中的值与数据库中的值匹配。如果值不匹配,它会将用户重定向到 AccountController 上的 Login 操作。
public class CheckSessionAttribute : ActionFilterAttribute, IAuthenticationFilter
public override void OnActionExecuting(ActionExecutingContext filterContext)
if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(AllowAnonymousAttribute), false).Any())
// If the action allows Anonymous users, no need to check the session
return;
var session = filterContext.RequestContext.HttpContext.Session;
var userName = filterContext.RequestContext.HttpContext.User.Identity.Name;
var userStore = new ApplicationUserStore(new IdentityDb());
var userManager = new ApplicationUserManager(userStore);
var user = userManager.FindByNameAsync(userName).Result;
if (userName == null || user == null || session == null || session["ActiveSessionId"] == null ||
session["ActiveSessionId"].ToString() != user.ActiveSessionId.ToString())
session.RemoveAll();
session.Clear();
session.Abandon();
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(new
action = "Login",
controller = "Account"
));
base.OnActionExecuting(filterContext);
[Authorize]
public class AccountController : Controller
[AllowAnonymous]
public ActionResult Login(string returnUrl)
SignOutAndKillSession();
ViewBag.ReturnUrl = returnUrl;
return View();
private void SignOutAndKillSession()
AuthenticationManager.SignOut();
Session.RemoveAll();
Session.Clear();
Session.Abandon();
当我被重定向到登录操作后再次尝试登录时,出现以下异常:
The provided anti-forgery token was meant for a different claims-based user than the current user
我在 Login 操作中设置了一个断点,可以看到在调用 SignOutAndKillSession() 之前和之后,User.Identity.Name 仍然设置为正在注销的用户。我相信这是导致页面呈现时生成不正确的 AntiForgeryToken 的原因。
有人可以帮助我了解如何在注销用户时清除用户主体吗?
谢谢
【问题讨论】:
【参考方案1】:对于遇到此问题的任何人,我通过使 MVC 5 在 CheckSessionAttribute 中创建的 cookie 过期来解决它。我还将属性从 ActionFilterAttribute 更改为 IAuthorizationFilter 属性
public class CheckSessionAttribute : FilterAttribute, IAuthorizationFilter
public void OnAuthorization(AuthorizationContext filterContext)
if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(AllowAnonymousAttribute), false).Any())
// If the action allows Anonymous users, no need to check the session
return;
var session = filterContext.RequestContext.HttpContext.Session;
var userName = filterContext.RequestContext.HttpContext.User.Identity.Name;
var userStore = new ApplicationUserStore(new IdentityDb());
var userManager = new ApplicationUserManager(userStore);
var user = userManager.FindByNameAsync(userName).Result;
if (userName == null || user == null || session == null || session["ActiveSessionId"] == null ||
session["ActiveSessionId"].ToString() != user.ActiveSessionId.ToString())
session.RemoveAll();
session.Clear();
session.Abandon();
ExpireCookie("ASP.NET_SessionId", filterContext);
ExpireCookie("__RequestVerificationToken", filterContext);
ExpireCookie(".AspNet.ApplicationCookie", filterContext);
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(new
action = "Login",
controller = "Account"
));
return;
private void ExpireCookie(string name, AuthorizationContext filterContext)
if (filterContext.RequestContext.HttpContext.Request.Cookies[name] != null)
filterContext.RequestContext.HttpContext.Response.Cookies[name].Value = string.Empty;
filterContext.RequestContext.HttpContext.Response.Cookies[name].Expires = DateTime.Now.AddMonths(-20);
【讨论】:
以上是关于使用自定义 ActionFilterAttribute 在 MVC 5 中注销用户的主要内容,如果未能解决你的问题,请参考以下文章
使用自定义动画删除自定义 UIStoryboardSegue