【问题标题】:How to get Antiforgery token before sending response?如何在发送响应之前获取防伪令牌?
【发布时间】:2021-08-30 20:11:49
【问题描述】:

我有 ASP.NET Core 应用程序,它会自动验证 AntiforgeryToken 的每个 POST 请求:

services.AddMvc(options =>
{                
    options.Filters.Add(new AuthorizeFilter(authorizationPolicy));
    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());                              
});

然后我有 Telerik 的 Kendo Grid,它为 Grid 使用 AJAX 绑定。网格中的一列有一个按钮,可以简单地执行表单 POST:

@(Html.Kendo().Grid<ItemModel>()
    .Name("SearchItems")
    .Columns(col =>
    {
        col.Bound(p => p.ID).Title("ID").Width(75);
        col.Bound(p => p.Name);                        
        col.Bound(p => p.ID).ClientTemplate("<form method='post' action='/items/#: ID #/copy'><button type='submit' class='btn btn-link'>copy</button></form>");
    })
    .AutoBind(true)
    .DataSource(dataSource => dataSource
        .Ajax()
        .Model(m=>m.Id(p=>p.WorkItemID))
        .PageSize(50)
        .ServerOperation(true)
        .Read(read => read.Action("Search", "Items"))
    )
)

控制器方法

[HttpPost]
[Route("items/search")]
public async Task<ActionResult> Search([DataSourceRequest] DataSourceRequest request)
{
    var workItems = await _Service.GetItems();
    var result = workItems.Select(x => new ItemModel()
    {
        ID = x.ID,
        Name = x.Name,
        Token = ?? // How do I get request verification token here

    }).ToList().ToDataSourceResult(request);
     
    return Json(result);
}
    
            
[HttpPost]
[Route("items/{id}/copy")]
public async Task<ActionResult> Copy([FromRoute]int id)
{
    // do something here
}

有没有办法在控制器的action方法中获取_RequestVarificationToken,这样我就可以在ClientTemplate中使用它并放到form里面了?

【问题讨论】:

    标签: asp.net-core asp.net-core-mvc kendo-grid asp.net-core-2.0 kendo-ui-mvc


    【解决方案1】:

    知道了。我必须注入 IAntiforgery 服务

    public class ItemsController : BaseController
    {
        private readonly IItemService _service;
        private readonly IAntiforgery _antiforgery;
        public ItemsController(IItemService service, IAntiforgery antiforgery)
        {
            _service = service;
            _antiforgery = antiforgery;
        }
        
        
        [HttpPost]
        [Route("items/search")]
        public async Task<ActionResult> Search([DataSourceRequest] DataSourceRequest request)
        {
            var token = _antiforgery.GetAndStoreTokens(HttpContext).RequestToken;
            var workItems = await _service.GetItems();
            var result = workItems.Select(x => new ItemModel()
            {
                ID = x.ID,
                Name = x.Name,
                Token = token
    
            }).ToList().ToDataSourceResult(request);
         
            return Json(result);
        }       
    

    }

    然后客户端模板将是

    col.Bound(p => p.ID).ClientTemplate("<form method='post' action='/items/#: ID #/copy'><input name='__RequestVerificationToken' type='hidden' value='#: Token #' /> <button type='submit' class='btn btn-link'>copy</button></form>");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-20
      • 2019-08-30
      • 1970-01-01
      • 2015-01-11
      • 1970-01-01
      • 2015-05-19
      • 1970-01-01
      相关资源
      最近更新 更多