ASP.NET MVC Ajax 请求安全

1.前言

ASP.NET MVC 应用通过使用AJAX请求来提升用户体验。AJAX请求不会刷新整个页面,用户几乎感知不到请求的发送和处理过程,正是这样,AJAX请求的安全性就十分重要了,如果有人伪造了请求,就很容易对应用进行攻击,从而泄露核心数据,导致安全问题。

2.解决方案

如何确保AJAX请求没有被伪造呢?解决办法就是在AJAX请求发起时传递给后台一个字符串,然后在Filter中进行校验。

3.例子

1)Model

namespace AntiForgeryTokenDemo.Models
{
    public class Person
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        private string age;

        public string Age
        {
            get { return age; }
            set { age = value; }
        }
    }
}
2)Index.cshtml

@model AntiForgeryTokenDemo.Models.Person
@{
    ViewBag.Title = "Home Page";
}

<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>

<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 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: $("#Name").val(), Age: $("#Age").val() },
                success: function (data) {
                    alert(data)
                },
                error: function () {
                    alert("Error")
                }
            });
        })

    })
</script>
3)Controller

public class HomeController : Controller
{
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        [MyValidateAntiForgeryToken]
        public ActionResult Index(Person p)
        {
            return Json(true, JsonRequestBehavior.AllowGet);
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
}
4)Filter

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;

namespace AntiForgeryTokenDemo.Filters
{
    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);
                }
            }
        }
    }
}
3.效果





修改AJAX请求的字符串后




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值