1

I'm trying to test out Anti Forgery tokens with API calls using VS2019 (C#) and RestSharp. What i'm doing is doing a GET to our login page to get 4 tokens/ cookies, then attaching these to a POST, with the Username and password, to try to log on. The first call succeeds and gives me a HTTP 200 and 4 cookies/ tokens back (ASP.NET_SessionId, XSRF-TOKEN, XSRF-COOKIE and a __RequestVerificationToken - all get attached as cookies (in the cookiecontainer) to the POST API call), the 2nd call however, fails with an HTTP 500 with this message: "Validation of the provided anti-forgery token failed. The cookie "__RequestVerificationToken" and the form field "__RequestVerificationToken" were swapped.". I'm including this token twice in my POST call - once as a cookie and once as part of the request body. Here is my code - can anyone shed any light on how to fix this error?

Thanks,

Jamie.

public void LogIn(string userName, string password)
{

    //  1st call to get the cookies and tokens.
    CommonProperties.Client = new RestClient { CookieContainer = new CookieContainer() };            

    CommonProperties.Client.BaseUrl = new Uri($"https://localhost:50000/Account/Login");
    var request = new RestRequest(Method.GET);
    request.AddParameter("ReturnUrl", "%2F", ParameterType.QueryString);
    CommonProperties.Response = CommonProperties.Client.Execute(request);   

    CommonProperties.Client.BaseUrl = new Uri($"https://localhost:50000/Account/Login");

    var requestToken = CommonProperties.Response.Cookies.Single(c => c.Name == 
            "__RequestVerificationToken");            

    //  2nd call to log in.
    request = new RestRequest(Method.POST);
    request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
    request.AddHeader("Accept-Encoding", "gzip, deflate, br");
    request.AddHeader("Accept", "*/*");
    request.AddHeader("Referer", $"https://localhost:50000/Account/Login");            
    request.AddParameter("undefined", $"__RequestVerificationToken= 
              {requestToken.Value}&UserName=userName&Password=password_321", ParameterType.RequestBody);

     CommonProperties.Response = CommonProperties.Client.Execute(request);            
 }
AardVark71
  • 3,928
  • 2
  • 30
  • 50

1 Answers1

0

I just solved this issue myself, so hopefully this answer helps anyone else who comes looking.

When you originally load the page with the GET it will return the cookie with the name of __RequestVerificationToken PLUS a form field with the same name. That form field will have a different value to the cookie's value, and in your POST you must set the body field for __RequestVerificationToken to have that form field's value, and the value of the cookie with the same name must match the cookie from the GET response.

If you have the same value for both the form field and the cookie, you get that rather misleading error that suggests the values are "swapped". They are not actually swapped, they're just matching, which is incorrect.

Bron Thulke
  • 388
  • 3
  • 19