繁体   English   中英

如何防止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 ,可以轻松地将Anti Forgery添加到Asp.Net Core MVC应用程序中。

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

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

你可以在这里阅读更多相关信息

只有在客户端共享cookie时才会发生CSRF攻击。 我的意思是客户可以访问来自多个域的cookie(例如,为您访问的每个站点存储cookie的Web浏览器)。 但是,Web应用程序API客户端通常只与单个域(您的API的域)联系。 任何跨站点攻击都不能在您的API中使用cookie,因为客户端未被共享(Web应用程序中的HTTP客户端与移动浏览器中的HTTP客户端是分开的 - 或者应该是)。 因此,如果API仅适用于您的移动应用程序,则您的Web应用程序API应该已经对CSRF安全。

这里讨论的webapi中有一个实现防伪标记的通用指南

在ASP.NET WebAPI中防止CSRF黑客攻击

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

1:使用WEBAPI端点:

您可以使用数据:通过Read传输的Data函数以常规方式发送防伪令牌

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操作系统

您需要在页面上添加此项以生成令牌

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

以下是将令牌发送到CRUD操作的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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM