System.Web.Mvc.HttpAntiForgeryException:MVC 5

使用 MVC 5.1.1/VS 2013 Professional/.Net 4.5

我偶尔会遇到错误(来自本地主机和生产 IIS 7):

System.Web.Mvc.HttpAntiForgeryException: The anti-forgery cookie token and form field token do not match.

问题似乎是当我注销用户时,有时当我再次进行身份验证时,那是我收到错误的时候。

我的身份验证代码如下所示:

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Login(LoginViewModel model)
    {
        if (ModelState.IsValid)
        {

            var user = _uow.UserRepository.FindLogin(model.Email, model.Password);
            if (user != null)
            {
                var claims = new List<Claim>();
                claims.Add(new Claim(ClaimTypes.Email, user.Email));
                claims.Add(new Claim(ClaimTypes.NameIdentifier, user.UserID.ToString()));
                claims.Add(new Claim(ClaimTypes.Role, user.UserLevel.ToString()));

                var id = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);

                var ctx = Request.GetOwinContext();
                var authenticationManager = ctx.Authentication;

                authenticationManager.SignIn(new AuthenticationProperties { IsPersistent = true }, id);

            }
            else
            {
                ModelState.AddModelError("", "Invalid Email Address or Password.");
            }
        }

        return View(model);
    }

使用 LogOut 方法更新:

    [HttpGet]
    [AllowAnonymous]
    public ActionResult LogOut(LoginViewModel model)
    {
        Session.Abandon();
        return SignOffUser();
    }

    private ActionResult SignOffUser()
    {
        AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
        return RedirectToAction("Index", "Home");
    }

注销表单视图

@if (Request.IsAuthenticated)
{
    using (Html.BeginForm(null, null, FormMethod.Post, new {id = "logoutForm", @class  = "navbar-right"}))
    {
        @Html.AntiForgeryToken()
        ....

    }
}
stack overflow System.Web.Mvc.HttpAntiForgeryException: MVC 5
原文答案

答案:

作者头像

显示您的注销表格(视图)。

如果您从视图中调用控制器中的注销方法,但在表单内部没有产生抗trogergerytoken,就会发生这种情况。

您的表格应该看起来像

@using(Html.BeginForm("Action","Controller"))
{
   @Html.antiforgerytoken()
   ....
}

然后您通过视图拨打的动作看起来像

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult MyAction()
{
   return content("hello user! Antiforgerytoken has been validated1");
}

PS:无论您的表格如何调用哪种操作方法,如果您想拥有需要验证的抗togrigergery令牌,则表格和动作方法应该看起来像我上面提到的内容。

作者头像

您可能要查看的另一件事是,在您的注销页面上,您不需要验证伪造令牌。

尝试改变这个:

[HttpGet]
[AllowAnonymous]
public ActionResult LogOut(LoginViewModel model)
{

对此

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult LogOut(LoginViewModel model)
{

我敢打赌,页面上的令牌正在发生变化,并且由于它没有经过验证,ASP.NET 不知道它是否真的正确。

E:刚刚注意到,它实际上应该是一个httppost on logout

作者头像

尝试在 web.config 中显式设置机器密钥(在 system.web 下):

 <machineKey validationKey="971E32D270A381E2B5954ECB4762CE401D0DF1608CAC303D527FA3DB5D70FA77667B8CF3153CE1F17C3FAF7839733A77E44000B3D8229E6E58D0C954AC2E796B" decryptionKey="1D5375942DA2B2C949798F272D3026421DDBD231757CA12C794E68E9F8CECA71" validation="SHA1" decryption="AES" />

这是一个生成唯一机器密钥的站点 http://www.developerfusion.com/tools/generatemachinekey/

链接: The anti-forgery cookie token and form field token do not match in MVC 4