0

Currently I am having a problem with my AntiForgeryToken not being present in my post call but for all I know, it is actually there.

Since I don't use a form to get the data from my HTML but just input fields I made a empty form on the bottom of my page using:

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = 
"__AjaxAntiForgeryForm" }))
{
    @Html.AntiForgeryToken()
}

This results in a AntiForgeryToken that I can get using jQuery.

so in my Javascript I do:

                        var LoginData = {
                            EmailAddress: currentMail,
                            Password: password
                        }
                        var form = $('#__AjaxAntiForgeryForm');
                        var token = $('input[name="__RequestVerificationToken"]', form).val();

                        data = {
                            __RequestVerificationToken: token,
                            LoginData: LoginData
                        }

                        $.post(window.location,
                            {
                                scController: '*Controller*',
                                scAction: 'ValidateLogin',
                                data: data
                            }).done(function (d, e) { 
                                console.log("done");
                                console.log(d);
                                console.log(e);
                            }).fail(function (d, e) {
                                console.log("error");
                                console.log(d);
                                console.log(e);
                            });

The data object that I create results in:

{LoginData: {EmailAddress: "********", Password: "*******"}, __RequestVerificationToken: "Imagine a token here"}

And then my controller action:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ResultMessage ValidateLogin(LoginData login)
    {
        return _userRepository.Login(login);
    }

For some reason when I try to do this post I get this error:

"The required anti-forgery form field "__RequestVerificationToken" is not present."

What am I doing wrong?

EDIT 1: I see that the __RequestVerificationToken in the Cookie header is different than the one I send with the data. How can this be?

Jelmer
  • 949
  • 3
  • 10
  • 23
  • Is the AntiForgeryToken cookie sent ? And why wouldn't you use a standard form? – Mik Nov 13 '17 at 09:06
  • @Mik Yes, in the Request Headers there is a Cookie header which includes: __RequestVerificationToken=xxxxxxxx; And because the input is in a SweetAlert so I can't/don't want to - use a form there. – Jelmer Nov 13 '17 at 09:11
  • @Mik I see that the __RequestVerificationToken in the Cookie header is different than the one I send with the data. How can this be? – Jelmer Nov 13 '17 at 09:14
  • I don't think they are supposed to be equal. Two values are generated. https://stackoverflow.com/questions/20911470/why-is-there-a-difference-in-the-validateantiforgerytoken-cookie-value-and-hidde – Mik Nov 13 '17 at 09:16

2 Answers2

0

As stated here https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks, when used with ajax, the anti-forgery token must be sent in the headers like this:

$.ajax("api/values", {
    type: "post",
    contentType: "application/json",
    data: {  }, // JSON data goes here
    dataType: "json",
    headers: {
        'RequestVerificationToken': <Token>
    }
});
Mik
  • 1,306
  • 1
  • 10
  • 14
0

Here is my step-by-step approach on this issue. I am using angularJS, jquery, ASP.NET MVC 5 https://stackoverflow.com/a/57781976/2508781

Use of MVC's AntiForgery.Validate() does the magic of validating the value of antiforgery token here and is wonderful so far. Hope this helps!

jitin14
  • 144
  • 5