如何在 ASP.NET Core MVC App Web API Controller 中防止 CSRF / XSRF

How-to prevent CSRF / XSRF in ASP.NET Core MVC App Web API Controller

通过将 ValidateAntiForgeryToken 属性应用于操作并在表单中使用 sp-antiforgery=true,可以轻松地向 Asp.Net 核心 MVC 应用程序添加防伪造.

如何保护 Web API 控制器的 CRUD 操作,该控制器在客户端使用 Authorize 属性和 Kendo MVC 网格进行个人身份验证?

A CSRF attack can only happen when cookies are shared on the client. By that I mean that the client has access to cookies from multiple domains (such as a web browser storing cookies for each site you visit). However, a web application API client typically only contacts a single domain (that of your API). Any cross site attack cannot use cookies within your API as the client is not shared (HTTP client in web application is separate than HTTP client in the mobile browser - or should be). Therefore your web application API should already be safe against CSRF if the API is for your mobile application only.

有一个通用指南用于在此处讨论的 webapi 中实现防伪令牌。

Preventing CSRF Hacks in ASP.NET WebAPI

但是由于您使用的是 kendo 网格,我们必须研究一些专门用于 Kendo 网格的东西。

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 的调用

我们会让你在 Datasource 中使用 Data 函数来发送防伪令牌给 CRUD ops

你需要在页面上添加这个来生成令牌

@Html.AntiForgeryToken()

然后在 kendo 网格数据源配置中执行此操作

.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"))
            )

这是将令牌发送到 CRUD ops

的 javascript 方法
<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());
        }

如需更多帮助,请查看 kendo 文档中的这些链接

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

您可以创建一个控制器并注入 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
        });
    }
}

您可以在 here

上阅读更多相关信息