当前位置:  开发笔记 > 编程语言 > 正文

如何解决在我的ASP.Net MVC应用程序中的iisreset之后发生的AntiForgeryToken异常?

如何解决《如何解决在我的ASP.NetMVC应用程序中的iisreset之后发生的AntiForgeryToken异常?》经验,为你挑选了4个好方法。

我在ASP.Net MVC中遇到AntiForgeryToken问题.如果我在我的网络服务器上执行iisreset并且用户继续他们的会话,他们会被退回到登录页面.并不可怕,但AntiForgery令牌爆炸,唯一的方法就是在浏览器上吹掉cookie.

对于版本1的beta版本,在我为我读回cookie时出错了所以我曾经在请求验证令牌之前擦除它,但在发布时已修复.

现在我想我会回到修复beta问题的代码,但我不禁想到我错过了什么.有没有一个更简单的解决方案,我应该放弃他们的助手并从头开始创建一个新的?我觉得很多问题是它与旧的ASP.Net管道如此紧密地联系在一起,并试图将其用于做一些它不是真正设计的事情.

我查看了ASP.Net MVC 2 RC的源代码,看起来代码没有太大变化,所以虽然我没有尝试过,但我认为没有任何答案.

这是异常的堆栈跟踪的相关部分.

编辑:我刚刚意识到我没有提到这只是试图在GET请求上插入令牌.这不是您开始执行POST时发生的验证.

System.Web.Mvc.HttpAntiForgeryException: A required anti-forgery token was not
supplied or was invalid.
---> System.Web.HttpException: Validation of viewstate MAC failed. If this 
application is hosted by a Web Farm or cluster, ensure that  
configuration specifies the same validationKey and validation algorithm. 
AutoGenerate cannot be used in a cluster.
---> System.Web.UI.ViewStateException: Invalid viewstate. 
  Client IP: 127.0.0.1
  Port: 4991
  User-Agent: scrubbed
  ViewState: scrubbed
  Referer: blah
  Path: /oursite/Account/Login
---> System.Security.Cryptography.CryptographicException: Padding is invalid and
cannot be removed.
at System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast)
at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo)
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)
--- End of inner exception stack trace ---
--- End of inner exception stack trace ---
at System.Web.UI.ViewStateException.ThrowError(Exception inner, String persistedState, String errorPageMessage, Boolean macValidationError)
at System.Web.UI.ViewStateException.ThrowMacValidationError(Exception inner, String persistedState)
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)
at System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Deserialize(String serializedState)
at System.Web.Mvc.AntiForgeryDataSerializer.Deserialize(String serializedToken)
--- End of inner exception stack trace ---
at System.Web.Mvc.AntiForgeryDataSerializer.Deserialize(String serializedToken)
at System.Web.Mvc.HtmlHelper.GetAntiForgeryTokenAndSetCookie(String salt, String domain, String path)
at System.Web.Mvc.HtmlHelper.AntiForgeryToken(String salt, String domain, String path)

Zhaph - Ben .. 42

如果您的MachineKey设置为AutoGenerate,那么您的验证令牌等将无法在应用程序重新启动后继续存在 - ASP.NET将在启动时生成新密钥,然后无法正确解密令牌.

如果你看到这么多,我建议:

    配置静态MachineKey(您应该能够在应用程序级别执行此操作),请参阅"如何:配置MachineKey"以获取更多信息

    尝试在使用站点时不执行IIS重置1

1执行此操作的最佳方法是使用loadbalanced应用程序,这将需要您设置静态MachineKey.另一个选择是通过放置站点app_offline.htm根目录中的文件来关闭站点,这将使站点脱机并显示您的消息 - 至少用户会期望出错.



1> Zhaph - Ben ..:

如果您的MachineKey设置为AutoGenerate,那么您的验证令牌等将无法在应用程序重新启动后继续存在 - ASP.NET将在启动时生成新密钥,然后无法正确解密令牌.

如果你看到这么多,我建议:

    配置静态MachineKey(您应该能够在应用程序级别执行此操作),请参阅"如何:配置MachineKey"以获取更多信息

    尝试在使用站点时不执行IIS重置1

1执行此操作的最佳方法是使用loadbalanced应用程序,这将需要您设置静态MachineKey.另一个选择是通过放置站点app_offline.htm根目录中的文件来关闭站点,这将使站点脱机并显示您的消息 - 至少用户会期望出错.


我有正确的机器密钥,但有时我有HttpAntiForgeryException.:(我不知道为什么.:/
以下是关于此主题的一些非常好的文章http://adam.kahtava.com/journal/2009/11/23/how-to-fix-the-validation-of-viewstate-mac-failed-error-aspnet-mvc/http://adam.kahtava.com/journal/2009/11/25/what-are-anti-cross-site-request-forgery-tokens-and-what-are-they-good-for/

2> Colin Newell..:

现在我已经使用了一个解决方案,如果抛出异常,它会擦除​​cookie.如果再次抛出异常,我会让它发生.

我不会将此标记为现在的'答案',希望有人有更好的答案.

public static class MyAntiForgeryExtensions
{
    // Methods
    public static string MyAntiForgeryToken(this HtmlHelper helper)
    {
        return MyAntiForgeryToken(helper, null);
    }

    public static string MyAntiForgeryToken(this HtmlHelper helper, string salt)
    {
        string fragment;
        string path = helper.ViewContext.HttpContext.Request.ApplicationPath;
        try
        {
            fragment = helper.AntiForgeryToken(salt, null, path);
        }
        catch (HttpAntiForgeryException)
        {
            // okay, scrub the cookie and have another go.
            string cookieName = GetAntiForgeryTokenName(path);
            helper.ViewContext.HttpContext.Request.Cookies.Remove(cookieName);
            fragment = helper.AntiForgeryToken(salt, null, path);
        }
        return fragment;
    }

    #region AntiForgeryData code that shouldn't be sealed
    // Copied from AntiForgeryData since they aren't accessible.
    internal static string GetAntiForgeryTokenName(string appPath) {
        if (String.IsNullOrEmpty(appPath)) {
            return "__RequestVerificationToken";
        }
        else {
            return "__RequestVerificationToken_" + Base64EncodeForCookieName(appPath);
        }
    }
    private static string Base64EncodeForCookieName(string s) {
        byte[] rawBytes = Encoding.UTF8.GetBytes(s);
        string base64String = Convert.ToBase64String(rawBytes);

        // replace base64-specific characters with characters that are safe for a cookie name
        return base64String.Replace('+', '.').Replace('/', '-').Replace('=', '_');
    }
    #endregion
}



3> JGilmartin..:

我有这个问题,并修复你需要做的是在你的web-config中添加一个显式的机器密钥...

 

确保将其置于web.config中...



我可能有点偏执,但是我不会使用任何互联网网站为我生成密钥。IIS的更高版本可以做到这一点,您也可以使用.NET系统类“ RNGCryptoServiceProvider”来实现。

4> 小智..:

您可以添加AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;global.asax

protected void Application_Start() {
    AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;
}

推荐阅读
Chloemw
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有