ASP.NET MVC Ajax 请求安全

来源:互联网 发布:bt.gg新域名 编辑:程序博客网 时间:2024/06/08 10:00

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 0
原创粉丝点击