切记ajax中要带上AntiForgeryToken防止CSRF攻击

from :https://www.jb51.net/article/73800.htm

经常看到在项目中ajax post数据到服务器不加防伪标记,造成CSRF攻击

在Asp.net Mvc里加入防伪标记很简单在表单中加入Html.AntiForgeryToken()即可。

Html.AntiForgeryToken()会生成一对加密的字符串,分别存放在Cookies 和 input 中。

我们在ajax post中也带上AntiForgeryToken

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 @model WebApplication1.Controllers.Person @{   ViewBag.Title = "Index" ; } <h2>Index</h2> <form id= "form1" >   <div class= "form-horizontal" >    <h4>Persen</h4>    <hr />    @Html.ValidationSummary( true , "" , new { @class = "text-danger" })    <div class= "form-group" >     @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })     <div class= "col-md-10" >      @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })      @Html.ValidationMessageFor(model => model.Name, "" , new { @class = "text-danger" })     </div>    </div>    <div class= "form-group" >     @Html.LabelFor(model => model.Age, htmlAttributes: new { @class = "control-label col-md-2" })     <div class= "col-md-10" >      @Html.EditorFor(model => model.Age, new { htmlAttributes = new { @class = "form-control" } })      @Html.ValidationMessageFor(model => model.Age, "" , new { @class = "text-danger" })     </div>    </div>    <div class= "form-group" >     <div class= "col-md-offset-2 col-md-10" >      <input type= "button" id= "save" value= "Create" class= "btn btn-default" />     </div>    </div>   </div> </form> <script src= "~/Scripts/jquery-1.10.2.min.js" ></script> <script src= "~/Scripts/jquery.validate.min.js" ></script> <script src= "~/Scripts/jquery.validate.unobtrusive.min.js" ></script> <script type= "text/javascript" >   $( function () {    //var token = $(‘[name=__RequestVerificationToken]‘);    //获取防伪标记    var token = $( ‘@Html.AntiForgeryToken()‘ ).val();    var headers = {};    //防伪标记放入headers    //也可以将防伪标记放入data    headers[ "__RequestVerificationToken" ] = token;    $( "#save" ).click( function () {     $.ajax({      type: ‘POST‘ ,      url: ‘/Home/Index‘ ,      cache: false ,      headers: headers,      data: { Name: "yangwen" , Age: "1" },      success: function (data) {       alert(data)      },      error: function () {       alert( "Error" )      }     });    })   }) </script>

放在cookies里面的加密字符串

控制器中代码

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Web; using System.Web.Helpers; using System.Web.Mvc; namespace WebApplication1.Controllers   {   public class HomeController : Controller    {    public ActionResult Index()     {     return View();     }    [HttpPost]    [MyValidateAntiForgeryToken]    public ActionResult Index(Person p)     {     return Json( true , JsonRequestBehavior.AllowGet);     }    }   public class Person    {    public string Name { get; set; }    public int Age { get; set; }    }   public class MyValidateAntiForgeryToken : AuthorizeAttribute    {    public override void OnAuthorization(AuthorizationContext filterContext)     {     var request = filterContext.HttpContext.Request;     if (request.HttpMethod == WebRequestMethods.Http.Post)           if (request.IsAjaxRequest())       {       var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName];       var cookieValue = antiForgeryCookie != null        ? antiForgeryCookie.Value        : null ;       //从cookies 和 Headers 中 验证防伪标记       //这里可以加try-catch       AntiForgery.Validate(cookieValue, request.Headers[ "__RequestVerificationToken" ]);       }      else       {       new ValidateAntiForgeryTokenAttribute()        .OnAuthorization(filterContext);       }      }     }    }   }

这里注释掉ajax中防伪标记在请求

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 $( "#save" ).click( function () {   $.ajax({    type: ‘POST‘ ,    url: ‘/Home/Index‘ ,    cache: false ,   //  headers: headers,    data: { Name: "yangwen" , Age: "1" },    success: function (data) {     alert(data)    },    error: function () {     alert( "Error" )    }   }); })

默认返回500的状态码。

这里修改ajax中的防伪标记

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24    $( function () {   //var token = $(‘[name=__RequestVerificationToken]‘);   //获取防伪标记   var token = $( ‘@Html.AntiForgeryToken()‘ ).val();   var headers = {};   //防伪标记放入headers   //也可以将防伪标记放入data   headers[ "__RequestVerificationToken" ] = token+11111111111111111111111111111111111;   $( "#save" ).click( function () {    $.ajax({     type: ‘POST‘ ,     url: ‘/Home/Index‘ ,     cache: false ,      headers: headers,     data: { Name: "yangwen" , Age: "1" },     success: function (data) {      alert(data)     },     error: function () {      alert( "Error" )     }    });   }) })

也是500的状态码。

以上内容就是本文的全部叙述,切记ajax中要带上AntiForgeryToken防止CSRF攻击,小伙伴们在使用过程发现有疑问,请给我留言,谢谢!

相关文章