确切位置在哪里把antiforgeryToken [英] Where exactly to put the antiforgeryToken

查看:324
本文介绍了确切位置在哪里把antiforgeryToken的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个与AntiForgeryToken形式布局页

I have a layout page that has a form with AntiForgeryToken

using (Html.BeginForm(action, "Account", new { ReturnUrl = returnUrl }, FormMethod.Post, new { Id = "xcrf-form" }))

这会生成一个隐藏字段

<input name="__RequestVerificationToken" type="hidden" value="p43bTJU6xjctQ-ETI7T0e_0lJX4UsbTz_IUjQjWddsu29Nx_UE5rcdOONiDhFcdjan88ngBe5_ZQbHTBieB2vVXgNJGNmfQpOm5ATPbifYE1">

在我的角度视图(即在布局页面的div被加载时,我这样做

In my angular view (that is loaded in a div in the layout page, I do this

<form class="form" role="form" ng-submit="postReview()">

和我的code为postReview()如下:

And my code for postReview() is as follows

$scope.postReview = function () {
    var token = $('[name=__RequestVerificationToken]').val();

    var config = {
        headers: {
            "Content-Type": "multipart/form-data",
            // the following when uncommented does not work either
            //'RequestVerificationToken' : token
            //"X-XSRF-TOKEN" : token
        }
    }

    // tried the following, since my other MVC controllers (non-angular) send the token as part of form data, this did not work though
    $scope.reviewModel.__RequestVerificationToken = token;

    // the following was mentioned in some link I found, this does not work either
    $http.defaults.headers.common['__RequestVerificationToken'] = token;

    $http.post('/Review/Create', $scope.reviewModel, config)
    .then(function (result) {
        // Success
        alert(result.data);
    }, function (error) {
        // Failure
        alert("Failed");
    });
}

我的MVC创建方法如下:

My MVC Create method is as follows

    [HttpPost]
    [ValidateAntiForgeryToken]
    [AllowAnonymous]
    public ActionResult Create([Bind(Include = "Id,CommentText,Vote")] ReviewModel reviewModel)
    {
        if (User.Identity.IsAuthenticated == false)
        {
            // I am doing this instead of [Authorize] because I dont want 302, which browser handles and I cant do client re-direction
            return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
        }

        // just for experimenting I have not yet added it to db, and simply returning
        return new JsonResult {Data = reviewModel, JsonRequestBehavior = JsonRequestBehavior.AllowGet};
    }

所以,无论身在何处,我把道理,不管我用'的Content-Type(我试过应用JSON和WWW的形式urlen codeD)我总是得到错误所需的抗伪造表单字段&QUOT; __ RequestVerificationToken&QUOT;不是present

So no matter where I put the token, no matter what I use for 'Content-Type' (I tried application-json and www-form-urlencoded) I always get the error "The required anti-forgery form field "__RequestVerificationToken" is not present."

我甚至尝试命名__RequestVerificationToken和RequestVerificationToken

I even tried naming __RequestVerificationToken and RequestVerificationToken

为什么我的服务器没有找到那个该死的令牌?

Why does my server not find the damn token?

我也看了几个,询问您是否实现自己的AntiForgeryToeknVerifyAttrbute并验证被作为cookieToken令牌链接:formToken,我还没有试过,但为什么我不能得到它的工作,而这个工作对MVC控制器(无棱角的职位)

I also looked at couple of links that ask you to implement your own AntiForgeryToeknVerifyAttrbute and verify the token that is sent as cookieToken:formToken, I have not tried that but why I am not able to get it working whereas this works for the MVC controllers (non-angular posts)

推荐答案

是的。默认情况下,MVC框架将检查的Request.Form [__ RequestVerificationToken]

Yes. By default, MVC Framework will check for Request.Form["__RequestVerificationToken"].

检查<大骨节病> MVC源$ C ​​$ C

    public AntiForgeryToken GetFormToken(HttpContextBase httpContext)
    {
        string value = httpContext.Request.Form[_config.FormFieldName];
        if (String.IsNullOrEmpty(value))
        {
            // did not exist
            return null;
        }

        return _serializer.Deserialize(value);
    }

您需要创建自己的过滤器,从 Request.Header

You need to create your own filter to check it from Request.Header

$ C $ ç片段从菲尔哈克的文章 - MVC 3

Code Snippet from Phil Haack's Article - MVC 3

private class JsonAntiForgeryHttpContextWrapper : HttpContextWrapper {
  readonly HttpRequestBase _request;
  public JsonAntiForgeryHttpContextWrapper(HttpContext httpContext)
    : base(httpContext) {
    _request = new JsonAntiForgeryHttpRequestWrapper(httpContext.Request);
  }

  public override HttpRequestBase Request {
    get {
      return _request;
    }
  }
}

private class JsonAntiForgeryHttpRequestWrapper : HttpRequestWrapper {
  readonly NameValueCollection _form;

  public JsonAntiForgeryHttpRequestWrapper(HttpRequest request)
    : base(request) {
    _form = new NameValueCollection(request.Form);
    if (request.Headers["__RequestVerificationToken"] != null) {
      _form["__RequestVerificationToken"] 
        = request.Headers["__RequestVerificationToken"];
    }
}

  public override NameValueCollection Form {
    get {
      return _form;
    }
  }
}

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, 
    AllowMultiple = false, Inherited = true)]
public class ValidateJsonAntiForgeryTokenAttribute : 
    FilterAttribute, IAuthorizationFilter {
  public void OnAuthorization(AuthorizationContext filterContext) {
    if (filterContext == null) {
      throw new ArgumentNullException("filterContext");
    }

    var httpContext = new JsonAntiForgeryHttpContextWrapper(HttpContext.Current);
    AntiForgery.Validate(httpContext, Salt ?? string.Empty);
  }

  public string Salt {
    get;
    set;
  }

  // The private context classes go here
}

查看这里 4 MVC实施 ,避免问题

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,
                AllowMultiple = false, Inherited = true)]
public sealed class ValidateJsonAntiForgeryTokenAttribute
                            : FilterAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        var httpContext = filterContext.HttpContext;
        var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];
        AntiForgery.Validate(cookie != null ? cookie.Value : null,
                             httpContext.Request.Headers["__RequestVerificationToken"]);
    }
}

这篇关于确切位置在哪里把antiforgeryToken的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆