如何在发送响应之前获得防伪令牌?



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

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

然后我有Telerik的剑道网格,这是使用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
}

是否有一种方法可以在控制器的动作方法中获得_RequestVarificationToken,以便我可以在ClientTemplate中使用它并将其放入表单中?

明白了。我必须注入防伪服务

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

最新更新