Correct usage of AntiForgery token in ASP.NET 5 in SPA application?
Asked Answered
I

2

8

In previous version of ASP.NET during SPA application the idea of AntiForgey token was following:

  • add @Html.AntiForgeryToken(); on the page
  • add __RequestVerificationToken to the request
  • ovverride AuthorizeAttribute as ValidateJsonAntiForgeryTokenAttribute.

I don't really understand the authorization requirements (is there some good information source?) in ASP.NET 5 but looks like new behavior should be like this:

  • add asp-anti-forgerytaghelper
  • add __RequestVerificationToken to the request
  • here should be the new requirement.

The question is: how to write this new authorization requirement and remove standard one? Could someone give some advice or point me on some example? Thanks

Isoprene answered 16/12, 2015 at 16:21 Comment(1)
Looks like I need to create custome middleware and check if it's json to use my way or use standard await _antiforgery.ValidateRequestAsync(context); But still not sure about it. Something like this github.com/aspnet/Antiforgery/blob/dev/samples/…Isoprene
M
1

With MVC6, if you use something like this:

<form asp-controller="Account" 
      asp-action="Login">
</form>

You will automatically get :

<form action="/Account/Login" method="post">
    <input name="__RequestVerificationToken" type="hidden" value="....">
</form>

asp-antiforgery would only be used if you want to deactivate that behavior.

As for the validation itself, it was added when you did app.AddMvc(...) in your ConfigureServices and Configure method.

In fact there's a bunch of stuff that is being added and if you are curious, you can check out the code!

If you really to generate this from an Action using then you could have a controller that depends on IHtmlGenerator and generate your token that way.

Melbourne answered 16/12, 2015 at 17:38 Comment(2)
Sorry if I wasn't clear. I agree with this, but it works only with MVC6 as you mentioned. I'm asking about SPA. How I should handle __RequestVerificationToken which was sent by Angular for instance, not as a form submit.Isoprene
Updated answer. Basically, it's generated from IHtmlGenerator which depends on IAntiForgery which depends on a whole different kind of crazy dependencies. If you need to ensure it is present that's the way to do it. Or you could just turn it off.Melbourne
F
0

In AspNetCore 1.1.0.0 (Maybe also in earlier versions) with a SPA scenario this is actually quite easy:

Make sure you deliver your index page from a .cshtml view and just add

@Html.AntiForgeryToken()

If you are using jquery you can then read this token and make sure it is sent with all future non-get requests inside a http-header

$(document).ajaxSend(function(e, xhr, options) {
    if (options.type.toUpperCase() != "GET") {
        xhr.setRequestHeader("RequestVerificationToken", $("input[name='__RequestVerificationToken']").val());
    }
});

Inside your controller method, just add

[HttpPost]
[ValidateAntiForgeryToken]
public string TestAntiForgery()
{
   return "success";
}

If you want/must use a differen header you can change it like this in configureServices:

services.Configure<AntiforgeryOptions>((options) =>
{
    // Configure a different header here
    options.HeaderName = "otherHeaderName";
});
Finfoot answered 4/12, 2016 at 18:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.