I am using IdentityServer 3 for authentication. When user is authenticated then IdentityServer makes a 'POST' request to client's application url. For example http://localhost/home so far so good everything is working fine.
My Client application is developed in ASP.NET Core. In client application i want to validate every POST request. So instead of adding ValidateAntiForgeryToken
attribute on each action method, i have created a middleware that validates every POST request.
public class ValidateAntiForgeryTokenMiddleware
{
private readonly RequestDelegate _next;
private readonly IAntiforgery _antiforgery;
public ValidateAntiForgeryTokenMiddleware(RequestDelegate next, IAntiforgery antiforgery)
{
_next = next;
_antiforgery = antiforgery;
}
public async Task Invoke(HttpContext httpContext)
{
if (httpContext.Request.Method.ToUpper() == "POST")
{
await _antiforgery.ValidateRequestAsync(httpContext);
}
await _next(httpContext);
}
}
The problem here is since identityserver is also making POST, the middleware tries to validate that request but the POST request fails with the following error
"The required antiforgery cookie \".AspNetCore.Antiforgery.AXelvXewLHI\" is not present."
In Identity Server i have custom login page. and i have configured anti-forgery-token in login page.
<div ng-show="model.loginUrl">
<div class="cr-login-dialog col-md-6 col-md-offset-3">
<form name="form" method="post" action="{{model.loginUrl}}" class="form-horizontal" role="form">
<anti-forgery-token token="model.antiForgery"></anti-forgery-token>
<div class="form-group">
//user name controls goes here
</div>
<div class="form-group">
//password controls goes here
</div>
<div class="form-group" ng-show="model.allowRememberMe">
// remember me controls goes here
</div>
</form>
</div>
</div>
You should separate out your anti-xsrf middleware to only run on your requests, not the requests to IdentityServer. IdentityServer does its own anti-xsrf token unrelated to MVC's implementation (as IdentityServer has no dependencies on MVC).