|
经常看到在项目中ajax post数据到服务器不加防伪标记,造成CSRF攻击,在Asp.net Mvc里加入防伪标记很简单在表单中加入Html.AntiForgeryToken()即可。
Html.AntiForgeryToken()会生成一对加密的字符串,分别存放在Cookies 和 input 中。我们在ajax post中也带上AntiForgeryToken
MVC中的Html.AntiForgeryToken()是用来防止跨站请求伪造(CSRF:Cross-site request forgery)攻击的一个措施,它跟XSS(XSS又叫CSS:Cross-Site-Script),攻击不同,XSS一般是利用站内信任的用户在网 站内插入恶意的脚本代码进行攻击,而CSRF则是伪造成受信任用户对网站进行攻击。 首先,我们视图代码如下:
- @{
- Layout = null;
- }
- <!DOCTYPE html>
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- <title>A1</title>
- <script src="~/Scripts/jquery-1.10.2.min.js"></script>
- </head>
- <body>
- <div>
- <button id="save" type="button">test</button>
- </div>
- <script type="text/javascript">
- $(function () {
- //获取防伪标记
- 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>
- </body>
- </html>
复制代码 运行起来,生成的html代码如下:
- <!DOCTYPE html>
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- <title>A1</title>
- <script src="/Scripts/jquery-1.10.2.min.js"></script>
- </head>
- <body>
- <div>
- <button id="save" type="button">test</button>
- </div>
- <script type="text/javascript">
- $(function () {
- //获取防伪标记
- var token = $('<input name="__RequestVerificationToken" type="hidden" value="h-MB0IrTwL2zXtG_1UExlbt5SL9nylyE2yRzT4en--Tjb4MP5-KX4N18bFTcDQ62992jJgFPIbE8w1P7AG8YuvVZW4YgKMXrcI-8uiS3qvg1" />').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>
- </body>
- </html>
复制代码
我们点击test按钮,去请求测试一下,看下是否带上了防伪造的cookie,如下图:
控制器中代码如下:
- [HttpPost]
- [ValidateAntiForgeryToken]
- public ActionResult Index(Person p)
- {
- return Json(true, JsonRequestBehavior.AllowGet);
- }
- }
- public class Person
- {
- public string Name { get; set; }
- public int Age { get; set; }
- }
复制代码 我们需要每个控制器里面里面加上ValidateAntiForgeryToken特性,如果用户没有带上AntiForgeryToken,我们可以返回给用户一个友好的提示,参考如下:
- 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);
- }
- }
- }
- }
复制代码
|
上一篇:asp.net mvc BindAttribute绑定特性下一篇:CMMI与Agile敏捷开发比较之一:两者的本质区别
|