asp.net-core - 如何在发送响应之前获取防伪令牌?
问题描述
我有 ASP.NET Core 应用程序,它自动验证每个 POST 请求AntiforgeryToken
:
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
}
有没有办法进入_RequestVarificationToken
控制器的操作方法,以便我可以在表单中使用它ClientTemplate
并将其放入表单中?
解决方案
知道了。我必须注入 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>");
推荐阅读
- html - 直到我将鼠标悬停在 SVG 线元素上才会呈现
- python - 如何在函数中使用 end="" with?
- tfs - TFS 2018 将 SharePoint 用于什么用途?
- r - diffinv 函数输出不是我想的那样
- python - 使用 sqlalchemy 的动态数据过滤器,它适用于给定值,但不适用于 NULL(None) 值
- flutter - 关于flutter的provider中出现的错误
- java - 运行 junit 时不支持的 major.minor 版本 52.0
- wordpress - 如何使用盐和密钥解密密码
- python - 在 python 中压缩和合并图像
- java - SimpleDateFormat.parse(date_string) 生成上一个日期