zoukankan      html  css  js  c++  java
  • 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的状态码。

  • 相关阅读:
    Leetcode 349. Intersection of Two Arrays
    hdu 1016 Prime Ring Problem
    map 树木品种
    油田合并
    函数学习
    Leetcode 103. Binary Tree Zigzag Level Order Traversal
    Leetcode 102. Binary Tree Level Order Traversal
    Leetcode 101. Symmetric Tree
    poj 2524 Ubiquitous Religions(宗教信仰)
    pat 1009. 说反话 (20)
  • 原文地址:https://www.cnblogs.com/soundcode/p/4884260.html
Copyright © 2011-2022 走看看