title: How can I implement the Anti-Forgery Token between MVC frontend and Web Api on different domains?
body: <ol>
  <li>I want to have the MVC project on <code>www.example1.com</code></li>
  <li>WebApi project on <code>api.example2.com</code></li>
  </ol>
  
  <p>I want to restrict the access to WebApi.
  I've tried to implement the Anti-Forgery Token:</p>
  
  <p>When I create the GET request to WebApi with Anti-forgery token then I get an exception because the request doesn't contains this token.</p>
  
  <p>In method called <code>ValidateRequestHeader</code> is variable <code>cookie = null</code>.</p>
  
  <p>How can I fix following code? Is this correct solution?</p>
  
  <p>MVC project (front-end) - for development is <code>localhost:33635</code>:</p>
  
  <p><strong>Index.cshtml</strong></p>
  
  <pre><code>&lt;div class="container"&gt;
  
  
      &lt;div class="row"&gt;
  
          &lt;div class="col-md-12"&gt;
  
  
              &lt;input id="get-request-button" type="button" class="btn btn-info" value="Create request to API Server" /&gt;
  
              &lt;br /&gt;
  
              &lt;div id="result"&gt;&lt;/div&gt;
  
          &lt;/div&gt;
  
  
      &lt;/div&gt;
  
  
  &lt;/div&gt;
  
  
  @section scripts
  {
  
      &lt;script type="text/javascript"&gt;
  
          @functions{
              public string TokenHeaderValue()
              {
                  string cookieToken, formToken;
                  AntiForgery.GetTokens(null, out cookieToken, out formToken);
                  return cookieToken + ":" + formToken;
              }
          }
  
          $(function () {
  
              $("#get-request-button").click(function () {
  
                  $.ajax("http://localhost:33887/api/values", {
                      type: "GET",
                      contentType: "application/json",
                      data: {},
                      dataType: "json",
                      headers: {
                          'RequestVerificationToken': '@TokenHeaderValue()'
                      }
                  }).done(function (data) {
                      $("#result").html(data);
                  });
  
                  return false;
              });
  
          });
  
  
      &lt;/script&gt;
  
  }
  </code></pre>
  
  <p>WebApi project - for development is <code>localhost:33887</code>:</p>
  
  <p><strong>WebApiConfig.cs</strong></p>
  
  <pre><code>public static void Register(HttpConfiguration config)
          {
              // Web API configuration and services
  
              config.EnableCors(new EnableCorsAttribute("http://localhost:33635", "*", "*"));
  
              // Web API routes
              config.MapHttpAttributeRoutes();
  
              config.Routes.MapHttpRoute(
                      name: "DefaultApi",
                      routeTemplate: "api/{controller}/{id}",
                      defaults: new { id = RouteParameter.Optional }
              );
          }
  </code></pre>
  
  <p><strong>ValidateHttpAntiForgeryTokenAttribute.cs:</strong></p>
  
  <pre><code>[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
      public sealed class ValidateHttpAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
      {
          public Task&lt;HttpResponseMessage&gt; ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func&lt;Task&lt;HttpResponseMessage&gt;&gt; continuation)
          {
              var request = actionContext.Request;
  
              try
              {
                  if (IsAjaxRequest(request))
                  {
                      ValidateRequestHeader(request);
                  }
                  else
                  {
                      AntiForgery.Validate();
                  }
              }
              catch (Exception)
              {
                  actionContext.Response = new HttpResponseMessage
                  {
                      StatusCode = HttpStatusCode.Forbidden,
                      RequestMessage = actionContext.ControllerContext.Request
                  };
                  return FromResult(actionContext.Response);
              }
              return continuation();
          }
  
          private Task&lt;HttpResponseMessage&gt; FromResult(HttpResponseMessage result)
          {
              var source = new TaskCompletionSource&lt;HttpResponseMessage&gt;();
              source.SetResult(result);
              return source.Task;
          }
  
          private bool IsAjaxRequest(HttpRequestMessage request)
          {
              IEnumerable&lt;string&gt; xRequestedWithHeaders;
              if (!request.Headers.TryGetValues("X-Requested-With", out xRequestedWithHeaders)) return false;
  
              var headerValue = xRequestedWithHeaders.FirstOrDefault();
  
              return !String.IsNullOrEmpty(headerValue) &amp;&amp; String.Equals(headerValue, "XMLHttpRequest", StringComparison.OrdinalIgnoreCase);
          }
  
          private void ValidateRequestHeader(HttpRequestMessage request)
          {
              var headers = request.Headers;
              var cookie = headers
                      .GetCookies()
                      .Select(c =&gt; c[AntiForgeryConfig.CookieName])
                      .FirstOrDefault();
  
              IEnumerable&lt;string&gt; xXsrfHeaders;
  
              if (headers.TryGetValues("RequestVerificationToken", out xXsrfHeaders))
              {
                  var rvt = xXsrfHeaders.FirstOrDefault();
  
                  if (cookie == null)
                  {
                      throw new InvalidOperationException($"Missing {AntiForgeryConfig.CookieName} cookie");
                  }
  
                  AntiForgery.Validate(cookie.Value, rvt);
              }
              else
              {
                  var headerBuilder = new StringBuilder();
  
                  headerBuilder.AppendLine("Missing X-XSRF-Token HTTP header:");
  
                  foreach (var header in headers)
                  {
                      headerBuilder.AppendFormat("- [{0}] = {1}", header.Key, header.Value);
                      headerBuilder.AppendLine();
                  }
  
                  throw new InvalidOperationException(headerBuilder.ToString());
              }
          }
      }
  </code></pre>
  
  <p><strong>ValuesController:</strong></p>
  
  <pre><code>public class ValuesController : ApiController
      {
          // GET: api/Values
          [ValidateHttpAntiForgeryToken]
          public IEnumerable&lt;string&gt; Get()
          {
              return new string[] { "value1", "value2" };
          }
  
          // GET: api/Values/5
          public string Get(int id)
          {
              return "value";
          }
  
          // POST: api/Values
          public void Post([FromBody]string value)
          {
          }
  
          // PUT: api/Values/5
          public void Put(int id, [FromBody]string value)
          {
          }
  
          // DELETE: api/Values/5
          public void Delete(int id)
          {
          }
      }
  </code></pre>