• 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',
                    url: '/Home/Index',
                    cache: false,
              //      headers: headers,
                    data: { Name: "yangwen", Age: "1" },
                    success: function (data) {
                        alert(data)
                    },
                    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',
                    url: '/Home/Index',
                    cache: false,
                   headers: headers,
                    data: { Name: "yangwen", Age: "1" },
                    success: function (data) {
                        alert(data)
                    },
                    error: function () {
                        alert("Error")
                    }
                });
            })
    
        })
    复制代码

    也是500的状态码。

  • 相关阅读:
    C#中的WebBrowser控件的使用
    触发器
    SQL Server存储机制
    mongodb客户端操作常用命令
    动态居中方法
    关于node不需要重启即可刷新页面
    测试一个段落里面是否含有数字
    表单验证
    关于echarts和jquery的结合使用问题
    js函数获取ev对象
  • 原文地址:https://www.cnblogs.com/soundcode/p/4884260.html
Copyright © 2020-2023  润新知