asp.net-mvc - validateantiforgerytoken - 必要な偽造防止 cookie "__requestverificationtoken" が存在しません。




各コントローラメソッドにValidateAntiForgeryToken属性が設定されていることを確認してください。 (3)

すべてのアクションメソッドに「ValidateAntiForgeryToken」属性が必要であるという強制を一元化する方法はありますか? 私はそれが "ルーティング"クラスを拡張することによって行われなければならないと考えています。

編集:またはアプリケーションの起動時に多少の反省をしますか?


OK、私はここでMVC v2.0にプロジェクトをアップグレードしました。あなたのコントローラアクションでAuthorizeAttributeを使用すると、eduncan911のソリューションはもはや動作しません。 それはなぜか分かりにくいものでした。

つまり、MVCチームがViewContext.HttpContext.User.Identity.Nameの値にViewContext.HttpContext.User.Identity.Nameプロパティーを追加したということです。

ベースコントローラーでオーバーライドされたOnAuthorizationは、コントローラーアクション上のフィルターの前に実行されます。 したがって、Authorize属性がまだ呼び出されていないため、 ViewContext.HttpContext.Userが設定されていないという問題があります。 したがって、UserNameはString.Emptyですが、検証に使用されるAntiForgeryTokenには実際のユーザー名=が含まれます。

このコードでこれを解決しました:

public abstract class MyBaseController : Controller
{
    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        //enforce anti-forgery stuff for HttpVerbs.Post
        if (String.Compare(filterContext.HttpContext.Request.HttpMethod, "post", true) == 0)
        {
            var authorize = new AuthorizeAttribute();
            authorize.OnAuthorization(filterContext);
            if (filterContext.Result != null) // Short circuit validation
                return;
            var forgery = new ValidateAntiForgeryTokenAttribute();
            forgery.OnAuthorization(filterContext);
        }
        base.OnAuthorization(filterContext);
    }
}

MVCコードベースへの参照:

ControllerActionInvoker#InvokeAuthorizationFilters()行283.同じ短絡です。 AntiForgeryData#GetUsername()行98.新しい機能。


あなたが "私はそれを設定するのを忘れた"というバグを防ぐようにしているように思えます。 もしそうなら、これを行う最も良い場所はカスタムのControllerActionInvokerです。

基本的には、AntiForgeryトークンを使用せずにMVCがアクションを検出するのを止めるだけです。

public class MustHaveAntiForgeryActionInvoker : ControllerActionInvoker
{
    protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName)
    {
        var foundAction = base.FindAction(controllerContext, controllerDescriptor, actionName);

        if( foundAction.GetCustomAttributes(typeof(ValidateAntiForgeryTokenAttribute), true ).Length == 0 )
            throw new InvalidOperationException("Can't find a secure action method to execute");

        return foundAction;
    }
}

次に、お使いのコントローラ、好ましくはベースコントローラで:

ActionInvoker = new MustHaveAntiForgeryActionInvoker();

そのカスタムを追加したいだけです。コントローラの基本クラスは、「厚い」傾向にあり、MVCの優れた拡張性ポイントを使用して、所属する場所に必要な機能をフックすることが常にベストプラクティスです。

以下は、MVCの拡張性ポイントの大部分の良いガイドです: http://codeclimber.net.nz/archive/2009/04/08/13-asp.net-mvc-extensibility-points-you-have-to-know.aspx : http://codeclimber.net.nz/archive/2009/04/08/13-asp.net-mvc-extensibility-points-you-have-to-know.aspx


はい。 これを行うには、Mvc Controllerを継承する独自のBaseControllerを作成し、OnAuthorization()をオーバーロードします。 それを強制する前にPOSTイベントであることを確認したい:

public abstract class MyBaseController : Controller
{
  protected override void OnAuthorization(AuthorizationContext filterContext)
  {
    //enforce anti-forgery stuff for HttpVerbs.Post
    if (String.Compare(filterContext.HttpContext.Request.HttpMethod,
          System.Net.WebRequestMethods.Http.Post, true) == 0)
    {
      var forgery = new ValidateAntiForgeryTokenAttribute();
      forgery.OnAuthorization(filterContext);
    }
    base.OnAuthorization(filterContext);
  }
}

一度それを持って、すべてのコントローラがこのMyBaseController(またはあなたがそれを呼び出すもの)から継承することを確認してください。 または、同じコードを好きな場合は、各コントローラーで行うこともできます。





security