切记ajax中要带上AntiForgeryToken防止CSRF攻击
经常看到在项目中ajaxpost数据到服务器不加防伪标记,造成CSRF攻击
在Asp.netMvc里加入防伪标记很简单在表单中加入Html.AntiForgeryToken()即可。
Html.AntiForgeryToken()会生成一对加密的字符串,分别存放在Cookies和input中。
我们在ajaxpost中也带上AntiForgeryToken
@modelWebApplication1.Controllers.Person @{ ViewBag.Title="Index"; } <h2>Index</h2> <formid="form1"> <divclass="form-horizontal"> <h4>Persen</h4> <hr/> @Html.ValidationSummary(true,"",new{@class="text-danger"}) <divclass="form-group"> @Html.LabelFor(model=>model.Name,htmlAttributes:new{@class="control-labelcol-md-2"}) <divclass="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> <divclass="form-group"> @Html.LabelFor(model=>model.Age,htmlAttributes:new{@class="control-labelcol-md-2"}) <divclass="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> <divclass="form-group"> <divclass="col-md-offset-2col-md-10"> <inputtype="button"id="save"value="Create"class="btnbtn-default"/> </div> </div> </div> </form> <scriptsrc="~/Scripts/jquery-1.10.2.min.js"></script> <scriptsrc="~/Scripts/jquery.validate.min.js"></script> <scriptsrc="~/Scripts/jquery.validate.unobtrusive.min.js"></script> <scripttype="text/javascript"> $(function(){ //vartoken=$('[name=__RequestVerificationToken]'); //获取防伪标记 vartoken=$('@Html.AntiForgeryToken()').val(); varheaders={}; //防伪标记放入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里面的加密字符串
控制器中代码
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Net; usingSystem.Web; usingSystem.Web.Helpers; usingSystem.Web.Mvc; namespaceWebApplication1.Controllers { publicclassHomeController:Controller { publicActionResultIndex() { returnView(); } [HttpPost] [MyValidateAntiForgeryToken] publicActionResultIndex(Personp) { returnJson(true,JsonRequestBehavior.AllowGet); } } publicclassPerson { publicstringName{get;set;} publicintAge{get;set;} } publicclassMyValidateAntiForgeryToken:AuthorizeAttribute { publicoverridevoidOnAuthorization(AuthorizationContextfilterContext) { varrequest=filterContext.HttpContext.Request; if(request.HttpMethod==WebRequestMethods.Http.Post) { if(request.IsAjaxRequest()) { varantiForgeryCookie=request.Cookies[AntiForgeryConfig.CookieName]; varcookieValue=antiForgeryCookie!=null ?antiForgeryCookie.Value :null; //从cookies和Headers中验证防伪标记 //这里可以加try-catch AntiForgery.Validate(cookieValue,request.Headers["__RequestVerificationToken"]); } else { newValidateAntiForgeryTokenAttribute() .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(){ //vartoken=$('[name=__RequestVerificationToken]'); //获取防伪标记 vartoken=$('@Html.AntiForgeryToken()').val(); varheaders={}; //防伪标记放入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的状态码。
以上内容就是本文的全部叙述,切记ajax中要带上AntiForgeryToken防止CSRF攻击,小伙伴们在使用过程发现有疑问,请给我留言,谢谢!