ajax中加上AntiForgeryToken防止CSRF攻击

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

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

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

我们在ajax post中也带上AntiForgeryToken

@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里面的加密字符串

控制器中代码


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中防伪标记在请求

  $("#save").click(function () {
            $.ajax({
                type: 'POST',//      headers: headers,error: function () {
                    alert("Error")
                }
            });
        })
默认返回500的状态码。

这里修改ajax中的防伪标记

   $(function () {

        //var token = $('[name=__RequestVerificationToken]');
        //获取防伪标记
        var token = $('@Html.AntiForgeryToken()').val();
        var headers = {};
        //防伪标记放入headers
        //也可以将防伪标记放入data
        headers["__RequestVerificationToken"] = token+11111111111111111111111111111111111;
        $("#save").click(function () {
            $.ajax({
                type: 'POST',error: function () {
                    alert("Error")
                }
            });
        })

    })

相关文章

IE6是一个非常老旧的网页浏览器,虽然现在很少人再使用它,但...
PHP中的count()函数是用来计算数组或容器中元素的个数。这个...
使用 AJAX(Asynchronous JavaScript and XML)技术可以在不...
Ajax(Asynchronous JavaScript and XML)是一种用于改进网页...
本文将介绍如何通过AJAX下载Excel文件流。通过AJAX,我们可以...
Ajax是一种用于客户端和服务器之间的异步通信技术。通过Ajax...