ASP.NET MVC 防止CSRF攻击

在前台表单中使用@Html.AntiForgeryToken(),在后台action上添加ValidateAntiForgeryToken特性

表单提交,防止CSRF攻击。

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    <p>
        <label>
            Username:</label><input name="username" /></p>
    <p>
        <label>
            Password:</label><input name="password" type="password" /></p>
    <input type="submit" value="登录" />
}
        [ValidateAntiForgeryToken]
        public ActionResult DoSth(string username, string password)
        {
            return Content("ASP.NET MVC中,表单提交防止CSRF。");
        }

使用AJAX提交。防止CSRF攻击

前台代码

@using (Html.BeginForm("Login", "Home"))
{
    <p>
        <label>
            Username:</label><input name="username" /></p>
    <p>
        <label>
            Password:</label><input name="password" type="password" /></p>
    <input type="submit" value="登录" />
    <input type="button" id="btn1" value="异步登录" />
}
<script src="../../JS/jquery-1.7.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $(function () {
        $("#btn1").click(function () {
            $.ajax({
                type: "Post",
                url: '@Url.Action("Login", "Home")',
                data: { "username": "vichin", "password": "123" }, //post请求,不需要key
                success: function (res) {
                    alert(res);
                },
                error: function (msg) {
                    alert(msg.responseText);
                }, headers: {
                    token: $('@Html.AntiForgeryToken()').val()
                    //如果表单中没有使用Html.AntiForgeryToken(),那么就用上面这种方式来获取token。
                    //如果页面上使用了,那么页面上就会生成name为__RequestVerificationToken的隐藏域。
                    //可以使用$('[name=__RequestVerificationToken]').val()来获取。
                }
            });
        });
    })
</script>

在后台代码中,需要增加过滤器。然后在请求的action上应用该过滤器。

    public class MyAntiForgeryTokenAttribute : 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 中 验证防伪标记
                    AntiForgery.Validate(cookieValue, request.Headers["__RequestVerificationToken"]);//这里可以加try-catch
                }
                else
                {
                    new ValidateAntiForgeryTokenAttribute().OnAuthorization(filterContext);
                }
            }
        }
    }
        [MyAntiForgeryToken]
        public ActionResult Login(string username, string password)
        {
            return Content("ASP.NET MVC中,表单提交防止CSRF。");
        }