网站首页 文章专栏 ASP.NET MVC 防范跨站请求伪造(CSRF)
ASP.NET MVC 防范跨站请求伪造(CSRF)
编辑时间:2017-01-11 22:09 作者:Absolutely 浏览:771 评论:2

上一篇博客简单介绍了下跨站请求伪造(以下简称CSRF),那么在ASP.NET MVC中如何防范CSRF

1.针对form表单的请求攻击,使用AntiForgeryToken令牌

ASP.NET MVC 的HtmlHelper类为我们提供了一个防止CSRF的方法。

在form表单中加入以下代码:

    @Html.AntiForgeryToken()


官方文档解释为:生成一个隐藏的窗体字段(防伪标记),在提交窗体时将验证此字段。

但仅仅这一行代码还不能实现令牌的验证,还需要在相应的动作方法上添加特性:

    [ValidateAntiForgeryToken]


添加此特性过后,如果请求的表单中没有@html.AntiForgeryToken将无法正确请求到此Action。

2.针对Ajax Post请求攻击,同样是使用Token

根据微软提供的防范方式,我们可以模仿一个类似的令牌,来验证。

首先,在呈现需要请求Action的页面的时候,用一个Session保存Token:

    Session["Token"] = "1234";
然后,在视图页面创建一个隐藏字段保存Token的值:


    <input id="token" type="hidden" name="token" value="@Session["Token"].ToString()" />
在Ajax请求的时候将token的值放在Http的headers中:


    var headers = {};
    headers['__RequestAntiForgeryToken'] = $("#token").val();

    $.ajax({
        type: "POST",
        headers: headers,
        data: "id=" + id,
        url: '@Url.Action("ActionName")',
        success: function (data) {
            alert("请求成功")
        },
        error: function (e) {
            alert(e.responseText);
        }
    });


最后,写一个过滤器,用来拦截Ajax请求,然后验证Token:

    public class CheckAntiForgeryTokenAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                string token = filterContext.HttpContext.Request.Headers["__RequestAntiForgeryToken"];
                if (token == null || token.ToString() != filterContext.HttpContext.Session["Token"].ToString())
                    return;
            }
        }
    }


大概能实现Ajax请求拦截,如果是Ajax请求,但headers中没有Token或者Token不正确,就直接拦截请求!


以上纯属个人想法,具体能否实现还有待验证!


    出处:不落阁

    地址:www.lyblogs.cn

    转载请注明出处

     

来说两句吧
最新评论
  • ゛天空ノ轉晴時
    ゛天空ノ轉晴時 2017-03-16 16:59:01

    对于ajax请求同样适用form请求!@Html.AntiForgeryToken() 会生成name=__RequestVerificationToken的控件,把这个作为其中一个参数进行传递即可

  • Absolutely
    Absolutely 2017-03-16 17:25:55
    应该是可以的