ASP.NET Core MVC anti forgery

非 Y 不嫁゛ 提交于 2019-12-21 19:27:43

问题


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

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>

And finally each client ajax request adds RequestVerificationToken this way.

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

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.

Any ideas?

UPDATE:

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

And here is the middleware registered:

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

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


回答1:


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

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

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

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

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

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

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.




回答2:


Make sure that both cookies have the same path:

You can change this in your antiforgery configuration options. If you are using fetch to make your calls make sure too that your are sending cookies including the credentials header.



来源:https://stackoverflow.com/questions/45254196/asp-net-core-mvc-anti-forgery

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!