在MVC 5中使用自定义ActionFilterAttribute注销用户
我有一个自定义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()之前的AND之前看到User.Identity.Name仍然设置为正在注销的用户。 我相信这是导致在页面呈现时生成不正确的AntiForgeryToken的原因。
有人可以帮助我了解在注销用户时如何清除用户主管?
谢谢
对于遇到此问题的任何人,我通过在CheckSessionAttribute内部过期使用由MVC 5创建的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);
}
}
}
链接地址: http://www.djcxy.com/p/74439.html
上一篇: Log Out a User in MVC 5 Using a Custom ActionFilterAttribute
下一篇: Returning a specific action result from a request filter