参考:

Preventing Cross-Site Request Forgery (CSRF) Attacks
Validating .NET MVC 4 anti forgery tokens in ajax requests

在mvc中,微软提供了一个简单的方法来防止CSRF,就是在前端form表单里加上Anti-Forgery Tokens

<form action="/Home/Test" method="post">
<input name="__RequestVerificationToken" type="hidden"
value="6fGBtLZmVBZ59oUad1Fr33BuPxANKY9q3Srr5y[...]" />
<input type="submit" value="Submit" />
</form>

razor的写法很简单:

@using (Html.BeginForm("Manage", "Account")) {
@Html.AntiForgeryToken()
}

后端只需要在action上加上[ValidateAntiForgeryToken]标签即可

//
// POST: /execute/uploadfile/
[HttpPost]
[MyValidateAntiForgeryToken]
public ActionResult UploadFile()
{
// codes here
}

那么ajax请求呢?
首先,我尝试在header里面加了__RequestVerificationToken,值就从razor生成,结果报错,最终发现还是要自定义,默认的[ValidateAntiForgeryToken]不行,所以我们就自定义一个MyValidateAntiForgeryTokenAttribute(片段1),需要注意以下几点:

  • 从filter中自己判断请求是不是ajax请求,如果你确实发起了ajax请求,还被Reauest.IsAjaxRequest()方法判定为false,那么检查一下header里面有没有{"X-Requested-With" : "XMLHttpRequest"}这个键和值
  • 既然是自定义过滤了,那么header里面这个键就没必要非得是__RequestVerificationToken了,你可以任意自定义,只要前后对应即可。
  • 至于如何取值,上面介绍了用@html扩展的写法,然后用js的方法把值取出来,也可以用下面片段2的写法,直接用razor写到js里面去,片段3中有使用方法(本例中一个angular的例子,注意甄别)
  • 最后,在应用的action前把系统默认的标签改成我们自定义的即可。

片段1,自定义的anti csrf过滤器

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MyValidateAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
{
private void ValidateRequestHeader(HttpRequestBase request)
{
string cookieToken = String.Empty;
string formToken = String.Empty;
string tokenValue = request.Headers["RequestVerificationToken"];
if (!String.IsNullOrEmpty(tokenValue))
{
string[] tokens = tokenValue.Split(':');
if (tokens.Length == 2)
{
cookieToken = tokens[0].Trim();
formToken = tokens[1].Trim();
}
}
AntiForgery.Validate(cookieToken, formToken);
} public void OnAuthorization(AuthorizationContext filterContext)
{ try
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
ValidateRequestHeader(filterContext.HttpContext.Request);
}
else
{
AntiForgery.Validate();
}
}
catch (HttpAntiForgeryException e)
{
throw new HttpAntiForgeryException("Anti forgery token cookie not found");
}
}
}

片段2,定义一个@function片断

@functions{
public string TokenHeaderValue()
{
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;
}
}

片段3, 使用定义的@function片断(实例为angular中为http请求添加全局的header)

var app = angular.module('srv', ['angularLocalStorage', 'angularFileUpload']);
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
$httpProvider.defaults.headers.common["RequestVerificationToken"] = '@TokenHeaderValue()';
}]);

asp.net MVC中防止跨站请求攻击(CSRF)的ajax用法的更多相关文章

  1. ASP.NET MVC中防止跨站请求攻击(CSRF)

    转载   http://kevintsengtw.blogspot.co.nz/2013/01/aspnet-mvc-validateantiforgerytoken.html 在 ASP.NET M ...

  2. ASP.NET MVC中设置跨域

    ASP.NET MVC中设置跨域 1.什么是跨域请求 js禁止向不是当前域名的网站发起一次ajax请求,即使成功respone了数据,但是你的js仍然会报错.这是JS的同源策略限制,JS控制的并不是我 ...

  3. js基础 js自执行函数、调用递归函数、圆括号运算符、函数声明的提升 js 布尔值 ASP.NET MVC中设置跨域

    js基础 目录 javascript基础 ESMAScript数据类型 DOM JS常用方法 回到顶部 javascript基础 常说的js包括三个部分:dom(文档document).bom(浏览器 ...

  4. ASP.NET Core-Docs:在 ASP.NET Core 中启用跨域请求(CORS)

    ylbtech-ASP.NET Core-Docs:在 ASP.NET Core 中启用跨域请求(CORS) 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部 1. ...

  5. 跨站请求伪造 CSRF / XSRF<一:介绍>

    跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一 ...

  6. PHP安全编程:跨站请求伪造CSRF的防御(转)

    跨站请求伪造(CSRF)是一种允许攻击者通过受害者发送任意HTTP请求的一类攻击方法.此处所指的受害者是一个不知情的同谋,所有的伪造请求都由他发起,而不是攻击者.这样,很你就很难确定哪些请求是属于跨站 ...

  7. 跨站请求伪造(CSRF)-简述

    跨站请求伪造(CSRF)-简述 跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 ...

  8. 跨站请求伪造(CSRF)攻击原理解析:比你所想的更危险

    跨站请求伪造(CSRF)攻击原理解析:比你所想的更危险 跨站请求伪造(Cross-Site Request Forgery)或许是最令人难以理解的一种攻击方式了,但也正因如此,它的危险性也被人们所低估 ...

  9. laravel之伪造跨站请求保护CSRF实现机制

    Laravel 提供了简单的方法使你的应用免受 跨站请求伪造 (CSRF) 的袭击.跨站请求伪造是一种恶意的攻击,它凭借已通过身份验证的用户身份来运行未经过授权的命令. Laravel 为每个活跃用户 ...

随机推荐

  1. python 6种数据类型几及用法

    #!/usr/bin/python3 #python的基本语法和数据类型 #python3中 一行有多个语句,用分号分割(;) print("aaa") ;print(" ...

  2. UIButton的竖排图片和文本

    UIButton的竖排图片和文本html, body {overflow-x: initial !important;}.CodeMirror { height: auto; } .CodeMirro ...

  3. facebook工具xhprof的安装与使用-分析php执行性能

    下载源码包的网址 http://pecl.php.net/package/xhprof

  4. 宇宙最强spacemacs

    这个标题背后的潜台词其实是:逼格是什么炼成的? 此处省略一万字. Emacs就不多说了,神之编辑器,但其快捷键实在是....Evil.好啦,现在来了Spacemacs,结合Vim与Emacs二者的优点 ...

  5. [Timer]应用层实现sleep

    转自:https://www.cnblogs.com/longbiao831/p/4556246.html Select只能做延时,可以做回调吗? 本文讲述如何使用select实现超级时钟.使用sel ...

  6. 设备接口体应用container_of的思考

    结构体应用container_of,可参考 container_of

  7. Redis (1) —— 安装

    Redis (1) -- 安装 摘要 介绍Mac OS X安装Redis基本方法 版本 Redis版本: 2.8.24 内容 下载Redis包 地址:http://download.redis.io/ ...

  8. H2O中的随机森林算法介绍及其项目实战(python实现)

    H2O中的随机森林算法介绍及其项目实战(python实现) 包的引入:from h2o.estimators.random_forest import H2ORandomForestEstimator ...

  9. 【jquery】基于 jquery 的翻牌效果 flip

    最近做了个类似于塔罗牌翻牌的效果,分享给大家. <!doctype html> <html lang="en"> <head> <meta ...

  10. 【Django】 积累

    ■ 数据库的长连接 众所周知,数据库的长连接可以在一定程度上提高整个应用的读写效率,节省创建和销毁数据库连接的成本.Django在1.6版本之后就已经支持了长连接的设置,是在settings中的DAT ...