asp.netcore mvc csrf 补充之 AutoValidateAntiForgeryToken——全局添加ValidateAntiForgeryToken
此随笔是对https://www.cnblogs.com/Fengyinyong/p/13039771.html 的补充
一.前端CSHtml 页面生成Token
在asp.netcore mvc 具体的action 返回的view中,也就是相应的.cshtml页面中,只要是method 为post的表单,都会自动生成一个隐藏域。如下图所示:
它是一个隐藏的input 元素,value的值,就是服务器端后端返回给页面的Token(具体通过什么返回的待研究)。每次刷新的时候(实质时通过action 访问.cshtml),后端都会更新返回的给相应视图的token。
前端关键代码:
method为post的表单,自动生成隐藏的input,该input value值是后端返回的Token。每次进入都会刷新。
@model MVCTemplate.Models.Student <h1>创建学生</h1> <div> <form method="post"> <label asp-for="FirstName"></label> <input asp-for="@Model.FirstName" /> <label asp-for="LastName"></label> <input asp-for="@Model.LastName" /> <label asp-for="Birthday"></label> <input asp-for="@Model.Birthday" type="date" /> <label asp-for="Gender"></label> <select asp-for="@Model.Gender" asp-items="@Html.GetEnumSelectList<Gender>()"></select> <button type="submit">保存数据</button> </form> </div>
返回视图的后端代码:
[HttpGet]//通过http动词来区分请求的是 哪个Create。 public IActionResult Create() { return View();//通过action返回的视图,才会在post的form上生成Token域 }
二、后端 ValidateAntiForgeryToken 校验Token
在后端的对应的方法上,加上ValidateAntiForgeryToken 属性,就可以对前端返回的Token进行校验,通过则进入方法,不通过则抛异常。
关键代码如下:
[HttpPost] //post 请求 [ValidateAntiForgeryToken]//用于防止跨站请求伪造,针对post的Action,一定要加上这个。 public IActionResult Create(Student stuModel) { if (!ModelState.IsValid) { return Content("数据输入有误"); } // todo.... 其他无关代码,这里就不贴出来了,省略了 }
注意:两个create 方法,通过http动词 post,get 来区分请求的是哪一个。
三、添加全局的ValidateAntiForgeryToken.
每一个post的方法,都要手动添加 ValidateAntiForgeryToken,太麻烦,而且很容易漏,可以在startup类中的ConfigureServices方法中添加一个全局的过滤器,在过滤器中使用AutoValidateForgeryTokenAttribute 添加全局的ValidateForgeryTokenAttribute。
关键代码如下:
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); //注册 Antiforgery,设置AntiForgeryToken信息,不设置,就使用默认的。 services.AddAntiforgery(options=> { options.FormFieldName = "AntiForgeryFieldName";//设置的是form中 input的 name属性 options.HeaderName = "csrf"; options.SuppressXFrameOptionsHeader = false; }); //注册一个全局的过滤器,这样全局的post 方法,都加上了ValidateAntiForgeryToken。不需要逐个添加。 services.AddMvc(options=> { options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); }); services.AddSingleton<IRepository<Student>, InMemoryRepository>();//注册容器,将服务添加到容器(注册服务)。 }
如果某个post 方法不想使用 防csfr,则在该方法上加上。IgnoreAntiforgeryToken 属性即可。
CSRF官网文档:https://docs.microsoft.com/zh-cn/aspnet/core/security/anti-request-forgery?view=aspnetcore-3.1