切记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攻击,小伙伴们在使用过程发现有疑问,请给我留言,谢谢!