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


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

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

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

    我们在ajax post中也带上AntiForgeryToken

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

    <script type="text/javascript">
        $("#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>
    

      

    默认返回500的状态码。

    这里修改ajax中的防伪标记

    <script type="text/javascript">
        $(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")
                    }
                });
            })
        })
    
    </script>
    

      

    也是500的状态码。

    以上内容就是本文的全部叙述,切记ajax中要带上AntiForgeryToken防止CSRF攻击。

  • 相关阅读:
    acdream 1738 世风日下的哗啦啦族I 分块
    hihocoder #1179 : 永恒游戏 暴力
    hihocoder #1178 : 计数 暴力
    hihocoder #1177 : 顺子 模拟
    刷了500道水题是什么体验?
    scu 4436: Easy Math 水题
    JVM系列三:JVM参数设置、分析
    Eclipse插件Target Management (RSE)
    修改jsp文件tomcat发布失败(Could not delete May be locked by another process)
    oracle中修改表名
  • 原文地址:https://www.cnblogs.com/wolfocme110/p/5623227.html
Copyright © 2020-2023  润新知