作者:董丹一只花 | 来源:互联网 | 2023-01-28 19:17
试图在核心mvc项目中打开防伪,但没有运气.做了什么:
添加过滤器以自动检查每个POST请求上的防伪标记.
services.AddMvc(o =>
{
o.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
令牌生成以这种方式添加到每个页面.
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery;
@{
var antiforgeryRequestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}
...
...
最后每个客户端ajax请求都添加了RequestVerificationToken
这种方式.
var optiOns= {
url: o.url, type: 'POST', data: o.params, headers: { 'RequestVerificationToken': antiforgeryToken } };
我可以看到每个ajax请求都有令牌,但我总是为任何POST请求获得400.如果我禁用过滤器,它可以正常工作.但是一旦我启用它,asp.net核心就会在每个POST请求上启动验证,它总是返回400.
有任何想法吗?
更新:
我按照评论中的说明进行操作,现在代码如下所示.ConfigureServices方法:
services.AddMvc(o => {
o.Filters.Add(new HandleAllExceptionsFilterFactory());
o.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
services.AddAntiforgery(o => o.COOKIEName = "XSRF-TOKEN");
这是注册的中间件:
app.Use(next => cOntext=> {
if (context.Request.Path == "/")
{
var antiforgery = app.ApplicationServices.GetService();
var token = antiforgery.GetAndStoreTokens(context);
context.Response.COOKIEs.Append("XSRF-TOKEN", token.RequestToken, new COOKIEOptions {HttpOnly= false});
}
return next(context);
});
我还删除了之前发送标头的任何客户端Javascript代码.但它仍然无效.
1> Travis Boatm..:
你很亲密,它比你想象的要简单得多.
首先,当你使用services.AddMvc();
防伪时已经添加了.无需添加任何过滤器,因此请删除它们.
然后你会想要改变你的防伪配置.
// Old
services.AddAntiforgery(o => o.COOKIEName = "XSRF-TOKEN");
// New
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
只有在使用ajax时才需要这样做.默认情况下,防伪系统仅考虑表单数据.
接下来,在您的视图中,您可以通过使用轻松生成防伪标记@Html.AntiForgeryToken()
.不需要所有额外的代码.你可以摆脱它.这将创建一个
带有令牌值的隐藏.如果您
使用标签帮助程序(例如asp-action
和),则会自动为您创建使用此文件asp-controller
.如果您不使用这些标记助手,则可以使用asp-antiforgery="true"
.
现在你的ajax请求可以使用隐藏
值.这是一个例子:
$.ajax({
method: "POST",
url: "/api/test",
data: data,
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
statusCode: {
200: function () {
alert("Success");
},
400: function () {
alert("Client error");
},
500: function () {
alert("Server error");
}
}
});
重要的是beforeSend
功能.这是您在设置中将请求标头设置为相同标头名称的位置Startup.cs
现在您需要做的就是添加[ValidateAntiForgeryToken]
您想要的方法.
最后在测试之前一定要删除你添加的中间件.
这只是一种方法.还有在官方文档中发现许多其他解决方案在这里.