C# 使用Ajax处理AntiForgeryToken发送

C# 使用Ajax处理AntiForgeryToken发送,c#,ajax,asp.net-mvc,antiforgerytoken,C#,Ajax,Asp.net Mvc,Antiforgerytoken,你好,我在听 我正在尝试发送包含AntiforgeryToken的Ajax请求。 下面是我的ajax请求: $(document).ready(function () { @functions{ public string TokenHeaderValue() { string cookieToken, formToken; AntiForgery.GetTokens(null, out cookieToke

你好,我在听

我正在尝试发送包含AntiforgeryToken的Ajax请求。 下面是我的ajax请求:

$(document).ready(function () {
    @functions{
        public string TokenHeaderValue()
        {
            string cookieToken, formToken;
            AntiForgery.GetTokens(null, out cookieToken, out formToken);
            return cookieToken + ":" + formToken;                
        }
    }
    $('.z').on('click', function (event) {
        event.preventDefault();
        $.ajax({
            url: "/DeviceUsage/Return",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType: 'html',
            headers: {
                'RequestVerificationToken': '@TokenHeaderValue()'
            },
            data: JSON.stringify({ dev: { DeviceInstanceId: $('#DeviceInstanceId').val(), UserId: "1", StorageId: $('#StorageId').val() } }),
            error: function (data) {
                alert("wystąpił nieokreślony błąd " + data);
            },
            success: function (data) {
                $('.modal-body').html(data);
            }
        })
    })
});
这里是我的控制器:

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Return(DeviceUsage dev)
    {
        if(dev.StorageId==3)
        {
            ModelState.AddModelError("", "Nie można oddać na własne biurko");
            ViewBag.StorageId = new SelectList(unitOfWork.storageRepository.Get(), "Id", "Name", dev.StorageId);
            return PartialView(dev);
        }
        dev.UserId = 1;
        unitOfWork.deviceUsageRepository.Update(dev);
        unitOfWork.Save();
        return RedirectToAction("MyDevices");
    }
但在本教程中,它们显示了如下功能:

void ValidateRequestHeader(HttpRequestMessage request)
{
string cookieToken = "";
string formToken = "";

IEnumerable<string> tokenHeaders;
if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
{
    string[] tokens = tokenHeaders.First().Split(':');
    if (tokens.Length == 2)
    {
        cookieToken = tokens[0].Trim();
        formToken = tokens[1].Trim();
    }
}
AntiForgery.Validate(cookieToken, formToken);
}
void ValidateRequestHeader(HttpRequestMessage请求)
{
字符串cookieToken=“”;
字符串formToken=“”;
IEnumerable标记头;
if(request.Headers.TryGetValues(“RequestVerificationToken”,out-tokenHeaders))
{
string[]tokens=tokenHeaders.First().Split(“:”);
if(tokens.Length==2)
{
cookieToken=tokens[0]。Trim();
formToken=tokens[1].Trim();
}
}
防伪。验证(cookieToken,formToken);
}
但是我不知道把代码放在我的控制器的什么地方,也不知道如何调用这个函数。有人能给我解释一下如何使用上述代码吗?

他们在教程的Anti-CSRF和AJAX部分展示的是一种非标准的令牌验证方法。在本例中,您不会使用
[ValidateAntiForgeryToken]
,而是手动运行验证。首先,在ajax调用中插入额外的头:

        headers: {
            'RequestVerificationToken': '@TokenHeaderValue()'
        },
然后在操作中读取并验证标头中的令牌:

[HttpPost]
public ActionResult Return(DeviceUsage dev)
{
    ValidateRequestHeader(Request);
    //process action
}
void ValidateRequestHeader(HttpRequestBase request)
{
    string cookieToken = "";
    string formToken = "";

    if (request.Headers["RequestVerificationToken"] != null)
    {
        string[] tokens = request.Headers["RequestVerificationToken"].Split(':');
        if (tokens.Length == 2)
        {
            cookieToken = tokens[0].Trim();
            formToken = tokens[1].Trim();
        }
    }
    AntiForgery.Validate(cookieToken, formToken);
}
请注意,
ValidateRequestHeader()
读取前面由jQuery调用设置的头。此外,我还稍微修改了该方法,以接受
HttpRequestBase

提示:为了避免向响应ajax调用的每个控制器添加
ValidateRequestHeader()
,请将其添加到基础控制器(如果有的话),并从基础控制器派生所有控制器。或者更好地使用您自己的
[ValidateAntiForgeryAjaxToken]
属性。

对于存在此问题的用户 公认的答案是好的,但正如他提到的那样 您应该为更干净的代码创建操作过滤器 我就是这样做的

创建扩展类和方法

在cshtml和ajax调用中使用它

创建一个ActionFilter

只需这样使用它:


你真了不起!我尝试了第一个响应,但我不知道如何创建操作过滤器!谢谢!!!!!!
 public static class ExtentionUtilty
{
    public static string TokenHeaderValue()
    {
        string cookieToken, formToken;
        AntiForgery.GetTokens(null, out cookieToken, out formToken);
        return cookieToken + ":" + formToken;
    }
}
$.ajax("api/values", {
    type: "post",
    contentType: "application/json",
    data: {  }, // JSON data goes here
    dataType: "json",
    headers: {
        'RequestVerificationToken': '@ExtentionUtilty.TokenHeaderValue()'
    } 
});
public class ValidateHeaderAntiForgeryAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string cookieToken = "";
        string formToken = "";
        if (filterContext.HttpContext.Request.Headers["RequestVerificationToken"] != null)
        {
            string[] tokens = filterContext.HttpContext.Request.Headers["RequestVerificationToken"].Split(':');
            if (tokens.Length == 2)
            {
                cookieToken = tokens[0].Trim();
                formToken = tokens[1].Trim();
            }
        }
        try
        {
            AntiForgery.Validate(cookieToken, formToken);
            base.OnActionExecuting(filterContext);
        }
        catch
        {
            filterContext.Result = new HttpNotFoundResult();
        }
    }
}
    [HttpPost]
    [ValidateHeaderAntiForgery]
    [Authorize(Roles = "Admin")]
    public ActionResult ActiveBoomSar(int id, modelDto model){}