JQuery Ajax вызывает и Html.AntiForgeryToken () - PullRequest
195 голосов
/ 02 ноября 2010

Я реализовал в своем приложении защиту от CSRF-атак , следуя информации, которую я прочитал в некоторых постах в блогах в Интернете. В частности эти посты были драйвером моей реализации

В основном в этих статьях и рекомендациях говорится, что для предотвращения атаки CSRF любой должен реализовать следующий код:

1) Добавьте [ValidateAntiForgeryToken] к каждому действию, которое принимает глагол POST Http

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SomeAction( SomeModel model ) {
}

2) Добавьте вспомогательный <%= Html.AntiForgeryToken() %> внутри форм, который отправляет данные на сервер

<div style="text-align:right; padding: 8px;">
    <%= Html.AntiForgeryToken() %>
    <input type="submit" id="btnSave" value="Save" />
</div>

Во всяком случае, в некоторых частях моего приложения я выполняю POST Ajax с jQuery на сервер, не имея никакой формы. Это происходит, например, когда я позволяю пользователю нажимать на изображение, чтобы выполнить определенное действие.

Предположим, у меня есть таблица со списком действий. У меня есть изображение в столбце таблицы с надписью «Пометить активность как выполненную», и когда пользователь нажимает на эту операцию, я выполняю Ajax POST, как в следующем примере:

$("a.markAsDone").click(function (event) {
    event.preventDefault();
    $.ajax({
        type: "post",
        dataType: "html",
        url: $(this).attr("rel"),
        data: {},
        success: function (response) {
            // ....
        }
    });
});

Как я могу использовать <%= Html.AntiForgeryToken() %> в этих случаях? Должен ли я включить вспомогательный вызов в параметр data вызова Ajax?

Извините за длинный пост и большое спасибо за помощь

EDIT

Согласно jayrdub ответ, который я использовал следующим образом

$("a.markAsDone").click(function (event) {
    event.preventDefault();
    $.ajax({
        type: "post",
        dataType: "html",
        url: $(this).attr("rel"),
        data: {
            AddAntiForgeryToken({}),
            id: parseInt($(this).attr("title"))
        },
        success: function (response) {
            // ....
        }
    });
});

Ответы [ 19 ]

3 голосов
/ 29 августа 2013

1. Определить функцию для получения токена с сервера

@function
{

        public string TokenHeaderValue()
        {
            string cookieToken, formToken;
            AntiForgery.GetTokens(null, out cookieToken, out formToken);
            return cookieToken + ":" + formToken;                
        }
}

2. Получить токен и установить заголовок перед отправкой на сервер

var token = '@TokenHeaderValue()';    

       $http({
           method: "POST",
           url: './MainBackend/MessageDelete',
           data: dataSend,
           headers: {
               'RequestVerificationToken': token
           }
       }).success(function (data) {
           alert(data)
       });

3. Проверка на сервере в HttpRequestBase для метода, который вы обрабатываете Post / get

        string cookieToken = "";
        string formToken = "";
        string[] tokens = Request.Headers["RequestVerificationToken"].Split(':');
            if (tokens.Length == 2)
            {
                cookieToken = tokens[0].Trim();
                formToken = tokens[1].Trim();
            }
        AntiForgery.Validate(cookieToken, formToken);
1 голос
/ 03 октября 2018

Вот самый простой способ, который я видел.Примечание. Убедитесь, что в вашем представлении есть "@ Html.AntiForgeryToken ()"

  $("a.markAsDone").click(function (event) {
        event.preventDefault();
        var sToken = document.getElementsByName("__RequestVerificationToken")[0].value;
        $.ajax({
            url: $(this).attr("rel"),
            type: "POST",
            contentType: "application/x-www-form-urlencoded",
            data: { '__RequestVerificationToken': sToken, 'id': parseInt($(this).attr("title")) }
        })
        .done(function (data) {
            //Process MVC Data here
        })
        .fail(function (jqXHR, textStatus, errorThrown) {
            //Process Failure here
        });
    });
1 голос
/ 27 февраля 2012

Я знаю, что прошло некоторое время с тех пор, как этот вопрос был опубликован, но я нашел действительно полезный ресурс, который обсуждает использование AntiForgeryToken и делает его менее трудным для использования. Он также предоставляет плагин jquery для простого включения токена защиты от подделки в вызовы AJAX:

Рецепты для защиты от подделки для ASP.NET MVC и AJAX

Я не очень помогаю, но, возможно, кто-то найдет это полезным.

0 голосов
/ 29 ноября 2018

Ладно, здесь много постов, ни одно из них не помогло мне, дни и дни в Google, и все равно больше я не дошел до того, что писал все приложение с нуля, а потом заметил этот маленький самородок в моем Интернете.confg

 <httpCookies requireSSL="false" domain="*.localLookup.net"/>

Теперь я не знаю, почему я его добавил, однако с тех пор заметил, что он игнорируется в режиме отладки, а не в рабочем режиме (IE установлен где-то в IIS)

Для меня решение было одним из двух вариантов, так как я не помню, почему я добавил его, я не могу быть уверен, что другие вещи не зависят от него, и, во-вторых, доменное имя должно быть в нижнем регистре, а TLD не похож на ive.сделано в * .localLookup.net

Может быть, это помогает, может быть, нет.Я надеюсь, что это поможет кому-то

0 голосов
/ 30 сентября 2018

первое использование @ Html.AntiForgeryToken () в html

 $.ajax({
        url: "@Url.Action("SomeMethod", "SomeController")",
        type: 'POST',
        data: JSON.stringify(jsonObject),
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        async: false,
        beforeSend: function (request) {
            request.setRequestHeader("RequestVerificationToken", $("[name='__RequestVerificationToken']").val());
        },
        success: function (msg) {
            alert(msg);
        }
0 голосов
/ 26 июня 2017

Я использую сообщение ajax для запуска метода удаления (случается из временной шкалы visjs, но это не очень важно) Вот что я сестренка:

Это мой Index.cshtml

@Scripts.Render("~/bundles/schedule")
@Styles.Render("~/bundles/visjs")
@Html.AntiForgeryToken()

<!-- div to attach schedule to -->
<div id='schedule'></div>

<!-- div to attach popups to -->
<div id='dialog-popup'></div>

Все, что я добавил здесь, было @Html.AntiForgeryToken(), чтобы токен появился на странице

Тогда в своем посте ajax я использовал:

$.ajax(
    {
        type: 'POST',
        url: '/ScheduleWorks/Delete/' + item.id,
        data: {
            '__RequestVerificationToken': 
            $("input[name='__RequestVerificationToken']").val()
              }
     }
);

Который добавляет значение токена, соскобленное со страницы, к опубликованным полям

До этого я пытался поместить значение в заголовки, но я получил ту же ошибку

Не стесняйтесь публиковать улучшения. Это, конечно, кажется простым подходом, который я могу понять

0 голосов
/ 01 сентября 2016
function DeletePersonel(id) {

    var data = new FormData();
    data.append("__RequestVerificationToken", "@HtmlHelper.GetAntiForgeryToken()");

    $.ajax({
        type: 'POST',
        url: '/Personel/Delete/' + id,
        data: data,
        cache: false,
        processData: false,
        contentType: false,
        success: function (result) {
        }
    });
}

public static class HtmlHelper {
    public static string GetAntiForgeryToken() {
        System.Text.RegularExpressions.Match value = 
                System.Text.RegularExpressions.Regex.Match(System.Web.Helpers.AntiForgery.GetHtml().ToString(), 
                        "(?:value=\")(.*)(?:\")");
        if (value.Success) {
            return value.Groups[1].Value;
        }
        return "";
    }
}
0 голосов
/ 09 ноября 2011

AntiforgeryToken - все еще боль, ни один из приведенных выше примеров не работал слово в слово для меня. Слишком много для там. Поэтому я объединил их всех. Нужен @ Html.AntiforgeryToken в форме, висящей вокруг iirc

Решено так:

function Forgizzle(eggs) {
    eggs.__RequestVerificationToken =  $($("input[name=__RequestVerificationToken]")[0]).val();
    return eggs;
}

$.ajax({
            url: url,
            type: 'post',
            data: Forgizzle({ id: id, sweets: milkway }),
});

Если сомневаетесь, добавьте еще знаки $ 1006 *

0 голосов
/ 03 октября 2014

Незначительное улучшение решения 360Airwalk. Это добавляет токен Anti Forgery в функцию javascript, поэтому @ Html.AntiForgeryToken () больше не нужно включать в каждое представление.

$(document).ready(function () {
    var securityToken = $('@Html.AntiForgeryToken()').attr('value');
    $('body').bind('ajaxSend', function (elm, xhr, s) {
        if (s.type == 'POST' && typeof securityToken != 'undefined') {
            if (s.data.length > 0) {
                s.data += "&__RequestVerificationToken=" + encodeURIComponent(securityToken);
            }
            else {
                s.data = "__RequestVerificationToken=" + encodeURIComponent(securityToken);
            }
        }
    });
});
...