微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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")
                }
            });
        })

    })

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐