阻止 ASP.NET MVC 应用程序中的跨站点请求伪造(CSRF)攻击 防伪令牌

87 篇文章 0 订阅
31 篇文章 0 订阅

目前我还没有弄明白CSRF的问题,按我的理解

在页面中使用  @Html.AntiForgeryToken()

在controller层加入[ValidateAntiForgeryToken]标签

就应该OK了

但是这样我的程序总是提示  所需的防伪表单字段“__RequestVerificationToken”不存在

找了很多博客,不是长篇大论,就是不清楚

最后在微软官网查到

https://docs.microsoft.com/zh-cn/aspnet/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks

感觉讲的比较简单明了

下面是我的代码,如果大家有更好的方法请给我留言!

JS代码如下   
 <script>
    @functions{
        public string TokenHeaderValue()
        {
            string cookieToken, formToken;
            AntiForgery.GetTokens(null, out cookieToken, out formToken);
            return cookieToken + ":" + formToken;
        }
    }

    $(function () { 
        getLanguageID()
    }); 

    function getLanguageID() {
    
        var LanguageID = localStorage.getItem("LanguageID");
        $('#SelectLanguage').val(LanguageID); 
 
        $.ajax({
            type: 'POST',
            url: '@Url.Action("SetLanguageID","Login")',
            headers: {
            'RequestVerificationToken': '@TokenHeaderValue()'
            },
            //contentType: "application/json; charset=utf-8",
            data: { 
                LanguageID: LanguageID,
            },
 
            async: false,
            dataType: "json",
            success: function (data) {
                console.log(data)
               // window.location.href = "/Login/Login";
             },
            error: function (message) {
                   // alert(message);
             }
        });
    }
 
 
    </script>

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using com.aaa.DAL2;
using com.aaa.ViewModels;

namespace aaa.Platform.WEB.Controllers
{    
    public class LoginController : BaseController
    {
        //
        // GET: /Login/ 
        [HttpGet]
        public  ActionResult Login()
        {
            return View();
        } 

        [HttpPost]
        [MyValidateAntiForgeryToken]
 
        public JsonResult SetLanguageID(LanguageModels lm)
        { 
            com.aaa.DAL2.User.SetLanguageID(lm);
            return Json("");
        } 
    }
}
using System;
using System.Collections.Generic;
using System.Net;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;
using System.Linq;
using System.Net.Http;

namespace aaa.Platform.WEB.Controllers
{  
    public class BaseController : Controller
    {   
    }

    public class MyValidateAntiForgeryToken : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        { 
            var request = filterContext.HttpContext.Request;
            var response = filterContext.HttpContext.Response;
            if (request.HttpMethod == WebRequestMethods.Http.Post)
            {
                if (request.IsAjaxRequest())
                { 

                    string cookieToken = "";
                    string formToken = "";

                    string[] tokens = request.Headers.GetValues("RequestVerificationToken").First().Split(':');
                    if (tokens.Length == 2)
                    {
                        cookieToken = tokens[0].Trim();
                        formToken = tokens[1].Trim();
                    }
            
                    AntiForgery.Validate(cookieToken, formToken); 
          
                }
                else
                {
                    new ValidateAntiForgeryTokenAttribute()
                     .OnAuthorization(filterContext);
                }
            }
        } 
    } 
}

 下面的代码是我这里调试成功的

现在发现最关键的地方是ajax的 data 中要有 __RequestVerificationToken:token, 加在header中的不起作用

  function setLanguageID() {
        var token = $('[name="__RequestVerificationToken"]').val();
        var LanguageID = $('#SelectLanguage').val();
        console.log(LanguageID) 
        localStorage.setItem("LanguageID",LanguageID)

 

        $.ajax({
            type: 'POST',
            url: '@Url.Action("SetLanguageID","Login")',
 
            data: {
                __RequestVerificationToken:token,
                LanguageID: LanguageID,
            },
 
            async: false,
            dataType: "json",
            success: function (data) {
                console.log(data);
                window.location.href = "/Login/Login";
            },
            error: function (message) {
                // alert(message);
            }
        });

    }
这里是controller代码
 
       [HttpPost]
        [ValidateAntiForgeryToken]
        public JsonResult SetLanguageID(LanguageModels lm)
        { 
            com.canmax.DAL2.User.SetLanguageID(lm);
            return Json("");
        }


下面是LanguageModels类要有__RequestVerificationToken即可
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace com.aaa.ViewModels
{
    public class LanguageModels
    {
        public int ID { get; set; }
        public string LanguageID { get;set;}
        public string ItemID { get; set; }
        public string ItemText { get; set; }
        public string __RequestVerificationToken { get; set; }
        
    }
 
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值