Как предотвратить CSRF / XSRF в контроллере веб-API приложений ASP.NET Core MVC

Добавить защиту от подделки в приложение MVC Asp.Net Core легко, применив атрибут ValidateAntiForgeryToken к действию и используя sp-antiforgery=true в форме.

Как я могу защитить CRUD-операцию контроллера веб-API, который использует индивидуальную аутентификацию с атрибутом Authorize и сеткой Kendo MVC на стороне клиента?


person Erich Brunner    schedule 14.02.2017    source источник
comment
Привет, Шон, спасибо за ценный ответ. Я проголосовал и сделал ответ. Сегодня я нашел только эту ссылку dotnetcurry.com/aspnet/ 890 / с 2013 года и хотел убедиться, что он по-прежнему работает с Asp.Net Core и Kendo UI для jQuery. ЕЩЕ РАЗ СПАСИБО !   -  person Erich Brunner    schedule 15.02.2017
comment
в любое время, сэр. Я дал ссылку на эту ссылку, а также на конкретную реализацию на основе кендо   -  person Sean Ch    schedule 15.02.2017


Ответы (2)


Вы можете создать контроллер и ввести IAntiforgery для получения XsrfToken, а затем отправить его с запросом на проверку.

[Route("api/[controller]")]
public class XsrfTokenController : Controller
{
    private readonly IAntiforgery _antiforgery;

    public XsrfTokenController(IAntiforgery antiforgery)
    {
        _antiforgery = antiforgery;
    }

    [HttpGet]
    public IActionResult Get()
    {
        var tokens = _antiforgery.GetAndStoreTokens(HttpContext);

        return new ObjectResult(new {
            token = tokens.RequestToken,
            tokenName = tokens.HeaderName
        });
    }
}

Подробнее об этом можно прочитать на здесь

person Ahmar    schedule 15.02.2017
comment
Как я могу добавить это в пользовательский интерфейс Kendo для jQuery Grid на стороне клиента? Спасибо. - person Erich Brunner; 15.02.2017
comment
@Ahmar: Как я могу обновить токен после успешного входа в систему? - person Pabodha Wimalasuriya; 12.10.2018

Атака CSRF может произойти только тогда, когда файлы cookie используются клиентом совместно. Под этим я подразумеваю, что клиент имеет доступ к файлам cookie из нескольких доменов (например, веб-браузер, хранящий файлы cookie для каждого посещаемого вами сайта). Однако клиент API веб-приложения обычно связывается только с одним доменом (доменом вашего API). Любая межсайтовая атака не может использовать файлы cookie в вашем API, поскольку клиент не является общим (HTTP-клиент в веб-приложении отличается от HTTP-клиента в мобильном браузере - или должен быть). Следовательно, API вашего веб-приложения уже должен быть защищен от CSRF, если API предназначен только для вашего мобильного приложения.

Здесь обсуждается общее руководство по внедрению токена защиты от подделки в webapi.

Предотвращение взлома CSRF в ASP.NET WebAPI

Но поскольку вы используете сетку кендо, нам нужно найти что-то, что работает специально для сетки кендо.

1: Использование конечной точки WEBAPI:

вы можете использовать данные: отправьте токен защиты от подделки обычным способом с помощью функции данных транспортного средства чтения.

transport: {
    read: {
        url: url,
        type: "POST",
        data: {
            __RequestVerificationToken: $("input[name=__RequestVerificationToken]").val()
        }
    }

Или с помощью карты параметров:

   @Html.AntiForgeryToken()

 <div id="grid"></div>
<script>
    $(document).ready(function () {
        $("#grid").kendoGrid({
            dataSource: {
                type: "json",
                transport: {
                    read: {
                        url: "/Home/GetProducts",
                        type: "POST"
                    },
                    update: {
                        url: "/Home/UpdateProduct",
                        type: "POST"
                    },
                    parameterMap: function (options, operation) {
                        options.__RequestVerificationToken = $("input[name=__RequestVerificationToken]").val();
                        return options;
                    }
                },
                schema: {
                    model: {
                        id: "ID",
                        fields: {
                            ID: { type: "number", editable: false },
                            Name: { type: "string" }
                        }
                    }
                },
                pageSize: 10
            },
            height: 250,
            filterable: true,
            sortable: true,
            pageable: true,
            editable: "inline",
            columns: ["ID", "Name", {command: "edit"}]
        });
    });
</script>

ваш контроллер webapi

        [ValidateAntiForgeryToken]
        public ActionResult GetProducts()
        {
            return Json(products);
        }

        [ValidateAntiForgeryToken]
        public void UpdateProduct(Product updatedProduct)
        {
            var product = products.FirstOrDefault(p => p.ID == updatedProduct.ID);
            UpdateModel(product);
        }

2: использование вызовов на основе Ajax

мы сделаем вам функцию данных в источнике данных для отправки токена защиты от подделки в CRUD ops

вам нужно будет добавить это на страницу, чтобы сгенерировать токен

@Html.AntiForgeryToken()

Затем в конфигурации источника данных сетки кендо сделайте это

.DataSource(dataSource => dataSource
                .Ajax()
                .Model(model=>model.Id(m=>m.PersonID))
                    .Read(read => read.Action("GetPersons","Home").Data("sendAntiForgery"))
                    .Update(up => up.Action("UpdatePerson", "Home").Data("sendAntiForgery"))
            )

Вот метод javascript, который отправит токен в CRUD ops

<script type="text/javascript">
    function sendAntiForgery() {
        return { "__RequestVerificationToken": $('input[name=__RequestVerificationToken]').val() }
    }
</script>

Контроллер на стороне сервера

        [ValidateAntiForgeryToken]
        public ActionResult GetPersons([DataSourceRequest] DataSourceRequest dsRequest)
        {
            var result = persons.ToDataSourceResult(dsRequest);
            return Json(result);
        }

        [ValidateAntiForgeryToken]
        public ActionResult UpdatePerson([DataSourceRequest] DataSourceRequest dsRequest, Person person)
        {
            if (person != null && ModelState.IsValid)
            {
                var toUpdate = persons.FirstOrDefault(p => p.PersonID == person.PersonID);
                TryUpdateModel(toUpdate);
            }


            return Json(ModelState.ToDataSourceResult());
        }

для получения дополнительной помощи просмотрите эти ссылки в документации по кендо

http://www.telerik.com/forums/kendo-grid-antiforgerytoken#fPGvzDjUyEahRPNaTEo_TA http://www.telerik.com/forums/anti-forgery-tokens#VA3XA6lbT0WgeOwOQ3w_nQ

person Sean Ch    schedule 14.02.2017
comment
Я получаю 400 (неверный запрос) с подходом 1.) на конечной точке / api / Read. Могу я написать вам по электронной почте? - person Erich Brunner; 15.02.2017