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

 

posted @ 2020-09-28 02:39  FrankFyy  阅读(300)  评论(0编辑  收藏  举报