1.前言
CSRF(Cross-site request forgery)跨站请求伪造,ASP.NET MVC 应用通过使用AJAX请求来提升用户体验,浏览器开发者工具可以一览众山小,就很容易伪造了请求对应用进行攻击,从而泄露核心数据,导致安全问题。微软自带AntiForgeryToken可以解决,而且语法简单(AJAX请求发起时传递给后台一个字符串,然后在Filter中进行校验)
2.场景如下
为了验证一个来自form post请求,还需要在目标action上增加自定义[AntiForgeryToken]特性,下面会介绍到这个自定义特性用法
???/// <summary> ???/// 首页 ???/// </summary> ???public class HomeController : Controller ???{ ???????/// <summary> ???????/// 用户登录了111111 ???????/// </summary> ???????/// <returns></returns> ???????public ActionResult Index() ???????{ ???????????return View(); ???????} ???????/// <summary> ???????/// Your application description page. ???????/// </summary> ???????/// <returns></returns> ???????public ActionResult About() ???????{ ???????????ViewBag.Message = "Your application description page."; ???????????return View(); ???????} ???????/// <summary> ???????/// Your contact page. ???????/// </summary> ???????/// <param name="name">姓名</param> ???????/// <returns></returns> ???????public ActionResult Contact(string name) ???????{ ???????????ViewBag.Message = "Your contact page."; ???????????return View(); ???????} ???????/// <summary> ???????/// ????????/// </summary> ???????/// <returns></returns> ???????public ActionResult Person() ???????{ ???????????return View(); ???????} ???????/// <summary> ???????/// ????????/// </summary> ???????/// <param name="Name"></param> ???????/// <param name="Age"></param> ???????/// <returns></returns> ???????[HttpPost] ???????[AntiForgeryToken] ???????public ActionResult UserInfo(string Name,string Age) ???????{ ???????????return Json(Name + Age); ???????} ???}
前端html中如何防范?
一句语法糖解决所有问题,通过在html页面上或者script中使用 Html.AntiForgeryToken(),然后赋值给ajax中headers
html页面上
1.html中使用@Html.AntiForgeryToken(),然后通过jquery中name,获取隐藏域value的值,再赋值给ajax中headers
2.var headToken=$(‘input[name="__RequestVerificationToken"]‘).val();
script中
<html><head> ???<meta name="viewport" content="width=device-width" /> ???<title>Person</title> ???<script src="~/Scripts/jquery-3.3.1.min.js"></script> ???<script src="~/Scripts/jquery.validate.js"></script> ???<script src="~/Scripts/jquery.validate.unobtrusive.js"></script></head><body> ???<form id="form1">
@*@Html.AntiForgeryToken()*@ ???????<div class="form-horizontal"> ???????????<div class="form-group"> ???????????????<div> ???????????????????姓名:<input type="text" name="name" value="" id="name" /> ???????????????????密码: ?<input type="text" name="age" value="" id="age" /> ???????????????</div> ???????????????<div class="col-md-offset-2 col-md-10"> ???????????????????<input type="button" id="save" value="Create" class="btn btn-default" /> ???????????????</div> ???????????</div> ???????</div> ???</form> ???<script> ???????$(function () { ????????????//获取防伪标记 ???????????var token = $(‘@Html.AntiForgeryToken()‘).val(); ???????????var headers = {}; ???????????//防伪标记放入headers ???????????//也可以将防伪标记放入data ???????????headers["__RequestVerificationToken"] = token; ???????????$("#save").click(function () { ???????????????$.ajax({ ???????????????????type: ‘POST‘, ???????????????????url: ‘/Home/UserInfo‘, ???????????????????cache: false, ???????????????????headers: headers, ???????????????????data: { Name: $("#name").val(), Age: $("#age").val() }, ???????????????????success: function (data) { ???????????????????????alert(data) ???????????????????}, ???????????????????error: function () { ???????????????????????alert("Error") ???????????????????} ???????????????}); ???????????}) ???????}); ???</script></body></html>
3.自定义AuthorizeAttribute属性
它主要检查
(1)请求的是否包含一个约定的AntiForgery名的cookie
(2)请求Headers是否有一个["__RequestVerificationToken"],并且不能为空,约定的AntiForgery名的cookie和Headers中的值是否匹配
public class AntiForgeryToken : AuthorizeAttribute ???{ ???????/// <summary> ???????/// ????????/// </summary> ???????/// <param name="filterContext"></param> ???????public override void OnAuthorization(AuthorizationContext filterContext) ???????{ ???????????var request = filterContext.HttpContext.Request; ???????????if (request.IsAjaxRequest()) ???????????{ ???????????????var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName]; ???????????????var cookieValue = antiForgeryCookie != null ? antiForgeryCookie.Value : null; ???????????????var headerValue = request.Headers["__RequestVerificationToken"]; ???????????????//获取head中的值 ?如果为空直接拒绝不往下走 ???????????????if (string.IsNullOrEmpty(headerValue)) ???????????????{ ???????????????????base.OnAuthorization(filterContext); ???????????????????return; ???????????????} ???????????????//从cookies 和 Headers 中 验证防伪标记 ???????????????AntiForgery.Validate(cookieValue,headerValue); ???????????} ???????} ???}
ASP.NET MVC ?Ajax ?伪造请求
原文地址:https://www.cnblogs.com/xiaobai123/p/9254847.html