ASP.NET Core MVC防伪 [英] ASP.NET Core MVC anti forgery

查看:132
本文介绍了ASP.NET Core MVC防伪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图在核心MVC项目中打开防伪功能,但是没有运气.做了什么:

Trying to turn on anti forgery in core mvc project but with no luck. What was done:

添加了过滤器,以便在每个POST请求中自动检查防伪令牌.

Filter added to automatically check anti forgery token on every POST request.

services.AddMvc(o =>
{
  o.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});

以这种方式将令牌生成添加到每个页面.

Token generation was added to each page this way.

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery;
@{
   var antiforgeryRequestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}
...
...
<script>
    var antiforgeryToken = @Json.Serialize(antiforgeryRequestToken);
</script>

最后,每个客户端ajax请求都以这种方式添加RequestVerificationToken.

And finally each client ajax request adds RequestVerificationToken this way.

var options = {
        url: o.url, type: 'POST', data: o.params, headers: { 'RequestVerificationToken': antiforgeryToken } };

我可以看到每个ajax请求都具有令牌,但是对于任何POST请求,我总是得到400.如果我禁用了过滤器,则可以正常工作.但是一旦启用它,asp.net核心将在每个POST请求上开始验证,并且始终返回400.

I can see each ajax request has the token but I am always getting 400 for any POST request. If I disable the filter, it works fine. But once I enable it, asp.net core starts verification on each POST request and it always returns me 400.

有什么想法吗?

更新:

我已经按照注释中的说明进行操作,现在代码如下所示. ConfigureServices方法:

I've followed the instructions I got in the comments and now the code looks like following. ConfigureServices method:

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代码.但这仍然行不通.

I also removed any client side javascript code that has been sending the header before. But it still doesn't work.

推荐答案

您很亲密,它比您想象的要简单得多.

You're close, it's much simpler than you think it is.

首先,当您使用services.AddMvc();时,已经添加了防伪.无需添加任何过滤器,因此将其删除.

First off, when you use services.AddMvc(); anti-forgery is already added. There's no need to add any filters, so remove those.

然后,您将要更改防伪配置.

Then you'll want to change your anti-forgery configuration.

// Old
services.AddAntiforgery(o => o.CookieName = "XSRF-TOKEN"); 
// New
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");

仅在使用ajax时才需要.默认情况下,防伪系统将仅考虑表单数据.

This is only required if you are using ajax. By default the anti-forgery system will only consider form data.

接下来,在您的视图中,您可以使用@Html.AntiForgeryToken()轻松生成防伪令牌.不需要所有这些额外的代码.您可以摆脱它.这将使用令牌的值创建一个隐藏的<input />.如果您使用<form />,则使用asp-actionasp-controller之类的标记帮助程序时,它将自动为您创建.如果您不使用这些标记助手,则可以使用asp-antiforgery="true".

Next, in your views you can easily generate an anti-forgery token by using @Html.AntiForgeryToken(). There's no need for all that extra code. You can get rid of it. This will create a hidden <input /> with the value of the token. If your using a <form /> this will automatically be created for you if you use tag helpers such as asp-action and asp-controller. If you don't use those tag helpers you can use then use asp-antiforgery="true".

现在,您的ajax请求可以使用隐藏的<input />值.这是一个示例:

Now your ajax request can consume the hidden <input /> value. Here's an example:

$.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

The important part is the beforeSend function. This is where you set the request header to the same header name in you setup in Startup.cs

现在您要做的就是将[ValidateAntiForgeryToken]添加到所需的方法中.

Now all you need to do is add [ValidateAntiForgeryToken] to the method you want.

最后,在测试之前,请确保删除添加的中间件.

Finally before you test be sure to remove the middleware you added.

这只是实现此目的的一种方法.在官方文档的此处.

This is only one way to do it. There are many other solutions found at the official documentation here.

这篇关于ASP.NET Core MVC防伪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆