web-dev-qa-db-ja.com

ViewStateUserKeyを設定すると、「ビューステートMACの検証に失敗しました」というエラーが表示されます

BasePageクラスには、すべてのASPXページから派生した次のものがあります。

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);
    ViewStateUserKey = Session.SessionID;
}

また、Web.configmachineKeyを設定しています。これは私の開発マシンでも発生するため、このエラーはWebファームが原因ではないと思います。

これで、ホストが.NET 3.5SP1にアップグレードされました。この更新後、上記のViewStateUserKey設定でコンパイルするたびに、ポストバックごとに「ビューステートMACの検証に失敗しました」というエラーが常に発生します。

私はここで何が間違っているのですか?この設定は、最新のフレームワークの更新でさらに必要になりますか?

16
Druid

OK-会話に1年遅れています-しかし、これはどのように正しい答えですか?これは、認証されたユーザーの場合にのみ適用され、ユーザー名はセッションIDGUIDよりもはるかに簡単に推測できるためViewStateUserKeyを使用します。

ところで、コードを一番上に「修正」したい場合は、セッションIDを使用しますが、セッションIDが毎回変更されないようにするには、セッション変数を設定する必要があります。例Session["Anything"] = DateTime.Now

ViewStateUserKey = Session.SessionID;

もちろん、これはセッションを使用することを前提としています。そうでない場合は、ユーザー名やCookieに保持されているその他のGUIDなど、使用する他のキーが必要です。

17

私は問題の決定的な原因を見つけるためにかなり周りを検索しました。マイクロソフトからのこの投稿は、さまざまな原因すべてを説明するのに本当に役立ちました。 http://support.Microsoft.com/kb/2915218 原因4は、無効なViewStateUserKeyValueである原因4です。

ViewStateUserKeyをSession.SessionIDまたはUser.Identity.Nameに設定しても機能しませんでした。

次の理由により、検証エラーが断続的に発生しました。 IISによってアプリケーションプールがリセットされると、セッションが事実上更新され、エラーが発生します。セッション固定を回避するために、ログイン時にセッションをドロップします。これもログイン時にエラーになります。

最終的に私たちのために働いたのは、現在VS2012で提供されているCookieベースのソリューションでした。

public partial class SiteMaster : MasterPage
{
    private const string AntiXsrfTokenKey = "__AntiXsrfToken";
    private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";
    private string _antiXsrfTokenValue;

    protected void Page_Init(object sender, EventArgs e)
    {
        //First, check for the existence of the Anti-XSS cookie
        var requestCookie = Request.Cookies[AntiXsrfTokenKey];
        Guid requestCookieGuidValue;

        //If the CSRF cookie is found, parse the token from the cookie.
        //Then, set the global page variable and view state user
        //key. The global variable will be used to validate that it matches in the view state form field in the Page.PreLoad
        //method.
        if (requestCookie != null
        && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
        {
            //Set the global token variable so the cookie value can be
            //validated against the value in the view state form field in
            //the Page.PreLoad method.
            _antiXsrfTokenValue = requestCookie.Value;

            //Set the view state user key, which will be validated by the
            //framework during each request
            Page.ViewStateUserKey = _antiXsrfTokenValue;
        }
        //If the CSRF cookie is not found, then this is a new session.
        else
        {
            //Generate a new Anti-XSRF token
            _antiXsrfTokenValue = Guid.NewGuid().ToString("N");

            //Set the view state user key, which will be validated by the
            //framework during each request
            Page.ViewStateUserKey = _antiXsrfTokenValue;

            //Create the non-persistent CSRF cookie
            var responseCookie = new HttpCookie(AntiXsrfTokenKey)
            {
                //Set the HttpOnly property to prevent the cookie from
                //being accessed by client side script
                HttpOnly = true,

                //Add the Anti-XSRF token to the cookie value
                Value = _antiXsrfTokenValue
            };

            //If we are using SSL, the cookie should be set to secure to
            //prevent it from being sent over HTTP connections
            if (FormsAuthentication.RequireSSL &&
            Request.IsSecureConnection)
            responseCookie.Secure = true;

            //Add the CSRF cookie to the response
            Response.Cookies.Set(responseCookie);
        }

            Page.PreLoad += master_Page_PreLoad;
        }

        protected void master_Page_PreLoad(object sender, EventArgs e)
        {
            //During the initial page load, add the Anti-XSRF token and user
            //name to the ViewState
            if (!IsPostBack)
            {
                //Set Anti-XSRF token
                ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey;

                //If a user name is assigned, set the user name
                ViewState[AntiXsrfUserNameKey] =
                Context.User.Identity.Name ?? String.Empty;
            }
            //During all subsequent post backs to the page, the token value from
            //the cookie should be validated against the token in the view state
            //form field. Additionally user name should be compared to the
            //authenticated users name
            else
            {
                //Validate the Anti-XSRF token
                if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue
                || (string)ViewState[AntiXsrfUserNameKey] !=
                (Context.User.Identity.Name ?? String.Empty))
            {
            throw new InvalidOperationException("Validation of
            Anti-XSRF token failed.");
            }
        }
    }
}

ソース

9
Vincejtl

今のところ、コードを次のように変更して修正しました。

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);

    if (User.Identity.IsAuthenticated)
        ViewStateUserKey = User.Identity.Name;
}
3
Druid

EnableViewStateMac @ Page属性を使用してViewStateMACエンコーディングをオフにできますか?

2
David Andres

非常に奇妙なことに、私も3日間同様の問題を抱えていましたが、今は解決しました。 1.フォーム認証を有効にし、SSLがfalseでした

<forms defaultUrl="~/" loginUrl="~/Account/Login.aspx" requireSSL="false" timeout="2880" />
  1. しかし、私のhttpcookiesタグには、requireSSL = trueがありました。 Site.Master.csではCookieを使用してViewStateUserKeyを設定しているため、問題が発生していました

  2. したがって、エラーが発生していました。

  3. これをfalseに変更し、Webアプリを再起動しましたが、すべて問題ありません。

0
Sundara Prabu