最近发现在错误日志教育经历添加过程中出现了提供的防伪标记适用于其他基于声明的用户,而不适用于当前用户得错误。经过测试,正常情况下是不会出现这个错误的。只在添加教育经历的时候,如果在另一个打开的窗口退出登录才会出现这个问题。
我是在控制器上实现的求职登录校验:
[PersonLoginCheckFilterAttribute(IsCheck = true)]然后在教育培训的action方法上实现的:
[ValidateAntiForgeryToken]防伪标记验证。
我的求职验证类是这样写的:
/// <summary>
/// 求职者是否登录判断
/// </summary>
public class PersonLoginCheckFilterAttribute : ActionFilterAttribute
{
/// <summary>
/// 表示是否检查登录
/// </summary>
public bool IsCheck { get; set; }
/// <summary>
/// Action方法执行之前执行此方法,校验求职者是否登录
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (IsCheck)
{
//校验用户是否已经登录
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
//跳转到登陆页
filterContext.Result = new RedirectResult("~/account/login", true);
//return;
}
var user = new LMIdentityDbContext().Users.Find(filterContext.HttpContext.User.Identity.GetUserId());
if (user == null || user.Role != "person")
{
//跳转到登陆页
filterContext.Result = new RedirectResult("~/account/login", true);
//return;
}
}
base.OnActionExecuting(filterContext);
}
}
由于继承的是ActionFilterAttribute,而我知道ActionFilterAttribute实现的是 IActionFilter, IResultFilter接口。
ValidateAntiForgeryToken方法我经过反编译,看到实现的接口是IAuthorizationFilter。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple =false, Inherited = true)]
public sealed class ValidateAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
我们都知道mvc的过滤器有四种。分别是:Authorization(授权),Action(行为),Result(结果)和Exception(异常)。异常哪个不说,执行顺序是先Authorization,后Action,最后是Result。按照常理,流程应该是这样得:当添加教育经历的时候,先判断是否登录,如果没登录,则跳转到登录页面,如果有登录则再在添加教育经历的action上验证ValidateAntiForgeryToken。这里直接报提供的防伪标记适用于其他基于声明的用户,而不适用于当前用户得错误,我推测是因为我的登录验证继承的Actionfilter,比ValidateAntiForgeryToken实现的接口IAuthorizationFilter要晚执行,导致了此错误的发生。因此决定修改此登录验证方法,继承AuthorizeAttribute方法,这样看能否解决问题。修改后的代码是这样得:
/// <summary>
/// 求职者是否登录判断
/// </summary>
public class PersonLoginCheckFilterAttribute : AuthorizeAttribute
{
/// <summary>
/// 表示是否检查登录
/// </summary>
public bool IsCheck { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool hasRole = base.AuthorizeCore(httpContext);
//如果为空,则表示尚未登录,为false
//EventLog.WriteLog("hasRole1:" + hasRole.ToString());
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
return hasRole;
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (IsCheck)
{
if (filterContext.HttpContext.User == null)
{
return;
}
if (filterContext.HttpContext.User.Identity == null)
{
return;
}
//校验用户是否已经登录
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
//跳转到登陆页
filterContext.Result = new RedirectResult("~/account/login", true);
return;
}
var user = new LMIdentityDbContext().Users.Find(filterContext.HttpContext.User.Identity.GetUserId());
if (user == null || user.Role != "person")
{
//跳转到登陆页
filterContext.Result = new RedirectResult("~/account/login", true);
return;
}
}
base.OnAuthorization(filterContext);
}
/// <summary>
/// 权限跳转类
/// </summary>
/// <param name="filterContext"></param>
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
base.HandleUnauthorizedRequest(filterContext);
}
}
修改后进行测试。打开添加教育经历页面,填写资料,然后又打开一个教育经历页面,在此页面退出登录,这时提交资料,自动跳转到了登录页面,不再出现提供的防伪标记适用于其他基于声明的用户,而不适用于当前用户得错误的提示了。问题解决