尝试在核心mvc项目中启用防伪,但没有运气。做了什么:
添加过滤器以自动检查每个POST请求上的防伪标记。
services.AddMvc(o =>
{
o.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
以这种方式向每个页面添加了令牌生成。
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery;
@{
var antiforgeryRequestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}
...
...
<script>
var antiforgeryToken = @Json.Serialize(antiforgeryRequestToken);
</script>
最后,每个客户端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<IAntiforgery>();
var token = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", token.RequestToken, new CookieOptions {HttpOnly = false});
}
return next(context);
});
我还删除了之前发送标头的任何客户端javascript代码。但它仍然无效。
答案 0 :(得分:7)
你关闭了,它比你想象的要简单得多。
首先,当您使用services.AddMvc();
防伪时已添加。没有必要添加任何过滤器,因此请删除它们。
然后您想要更改防伪配置。
// Old
services.AddAntiforgery(o => o.CookieName = "XSRF-TOKEN");
// New
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
只有在使用ajax时才需要这样做。默认情况下,防伪系统只会考虑表单数据。
接下来,在您的观看中,您可以使用@Html.AntiForgeryToken()
轻松生成防伪令牌。不需要所有额外的代码。你可以摆脱它。这将创建一个隐藏的<input />
,其中包含令牌的值。如果您使用<form />
,则会自动为您创建此项,如果您使用asp-action
和asp-controller
等标记帮助程序。如果您不使用这些标记帮助程序,则可以使用asp-antiforgery="true"
。
现在,您的ajax请求可以使用隐藏的<input />
值。这是一个例子:
$.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]
添加到您想要的方法中。
最后在测试之前一定要删除你添加的中间件。
这只是一种方法。官方文档here中提供了许多其他解决方案。
答案 1 :(得分:0)