切记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" ;
}

Index

"form1" >
 
"form-horizontal" >
  

Persen

  
   @Html.ValidationSummary( true , "" , new { @class = "text-danger" })
  
"form-group" >
    @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
   
"col-md-10" >
     @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
     @Html.ValidationMessageFor(model => model.Name, "" , new { @class = "text-danger" })
   
  
  
"form-group" >
    @Html.LabelFor(model => model.Age, htmlAttributes: new { @class = "control-label col-md-2" })
   
"col-md-10" >
     @Html.EditorFor(model => model.Age, new { htmlAttributes = new { @class = "form-control" } })
     @Html.ValidationMessageFor(model => model.Age, "" , new { @class = "text-danger" })
   
  
  
"form-group" >
   
"col-md-offset-2 col-md-10" >
     "button" id= "save" value= "Create" class= "btn btn-default" />
   
  
 

放在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攻击,小伙伴们在使用过程发现有疑问,请给我留言,谢谢!

你可能感兴趣的:(切记ajax中要带上AntiForgeryToken防止CSRF攻击)