If you're using ui-router you can do something like the following. The beauty of this approach is that it only happens on state change not on every request to the server. If you're developing a SPA, and using any templates this will come in handy:
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
if (IsAuthenticated()) {
SetAntiForgeryCookie();
}
});
SetAntiForgeryCookey just does a $http GET request that calls a simple action:
[HttpGet]
public IActionResult Get()
{
var context = Request.HttpContext;
var tokens = _antiForgery.GetAndStoreTokens(context);
context.Response.Cookies
.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
return new ObjectResult(true);
}
Then I create an attribute to apply to my actions:
public class ValidateApiAntiForgeryTokenAttribute : ActionFilterAttribute
{
private readonly IAntiforgery _antiForgery;
public ValidateApiAntiForgeryTokenAttribute(IAntiforgery antiForgery)
{
_antiForgery = antiForgery;
}
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
await _antiForgery.ValidateRequestAsync(context.HttpContext);
await base.OnActionExecutionAsync(context, next);
}
}
The only thing I dont like about this approach is that in order to inject into the attribute I have to use the ServiceFilterAttribute on the action:
[ServiceFilter(typeof(ValidateApiAntiForgeryTokenAttribute))]
Also dont forget the middleware in ConfigureServices:
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");