ASP.NET MVC 防止CSRF攻击
CSRF:跨站请求伪造。
A和B都在访问淘宝,A下订单买一台手机,将生成的链接通过QQ发送给B,然后B不明就里的打开了链接,就算是支付成功了(假定购买东西不需要二次密码验证,只需要登录淘宝网站就可以了。登录网站之后,会生成一个cookie在浏览器中,再次浏览该网页,因为cookie没有失效,所以不需要再次登录进行确认)。
在前台表单中使用@Html.AntiForgeryToken(),这样服务器在渲染页面的时候,会生成一个默认名为__RequestVerificationToken的cookie,并在页面上生成一个隐藏域,name也是__RequestVerificationToken;
在后台action上添加ValidateAntiForgeryToken特性。作用有2;1、请求的是否包含一个约定的AntiForgery名的cookie。2、请求是否有一个Request.Form["约定的AntiForgery名"],约定的AntiForgery名的cookie和Request.Form值是否匹配。
只针对Post方法有效,Get方法无效。
表单提交,防止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() //如果页面上使用了,那么页面上就会生成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。"); }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步