title: ASP.NET Core MVC anti forgery
body: <p>Trying to turn on anti forgery in core mvc project but with no luck. What was done:</p>
  
  <p>Filter added to automatically check anti forgery token on every POST request.</p>
  
  <pre><code>services.AddMvc(o =&gt;
  {
    o.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
  });
  </code></pre>
  
  <p>Token generation was added to each page this way.</p>
  
  <pre><code>@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery;
  @{
     var antiforgeryRequestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
  }
  ...
  ...
  &lt;script&gt;
      var antiforgeryToken = @Json.Serialize(antiforgeryRequestToken);
  &lt;/script&gt;
  </code></pre>
  
  <p>And finally each client ajax request adds <code>RequestVerificationToken</code> this way.</p>
  
  <pre><code>var options = {
          url: o.url, type: 'POST', data: o.params, headers: { 'RequestVerificationToken': antiforgeryToken } };
  </code></pre>
  
  <p>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.</p>
  
  <p>Any ideas?</p>
  
  <p>UPDATE:</p>
  
  <p>I've followed the instructions I got in the comments and now the code looks like following. ConfigureServices method:</p>
  
  <pre><code>services.AddMvc(o =&gt; { 
    o.Filters.Add(new HandleAllExceptionsFilterFactory()); 
    o.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); 
  }); 
  
  services.AddAntiforgery(o =&gt; o.CookieName = "XSRF-TOKEN");
  </code></pre>
  
  <p>And here is the middleware registered:</p>
  
  <pre><code>app.Use(next =&gt; context =&gt; { 
  if (context.Request.Path == "/") 
  { 
      var antiforgery = app.ApplicationServices.GetService&lt;IAntiforgery&gt;(); 
      var token = antiforgery.GetAndStoreTokens(context); 
      context.Response.Cookies.Append("XSRF-TOKEN", token.RequestToken, new CookieOptions {HttpOnly = false}); 
  } 
  
  return next(context); 
  });
  </code></pre>
  
  <p>I also removed any client side javascript code that has been sending the header before. But it still doesn't work.</p>