I want to use AntiForge Token in an Angular project
I have also written the back-end with ASP.NET Core
middleware code is
if (path != null)
{
var tokens = _antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append(
key: "XSRF-TOKEN",
value: tokens.RequestToken,
options: new CookieOptions
{
Path="/",
HttpOnly = false // Now JavaScript is able to read the cookie
});
}
return _next(context);
\\startup
app.UseAntiforgeryToken();
services.AddAntiforgery(x => x.HeaderName = "X-XSRF-TOKEN");
But what happens if I use ValidateAntiForgeryToken, my function does not run because the XSRF-TOKEN cookie is not sent to it.
headers = headers.set('Content-Type', 'application/json; charset=utf-8');
return this._httpClient.post(environment.authUrl+ 'api/Account/login',credentials,{headers: headers }).pipe(
switchMap((response: any) => {
// Store the access token in the local storage
this.accessToken = response.access_token;
this.refreshToken = response.refresh_token;
// Set the authenticated flag to true
this._authenticated = true;
//Store the user on the user service
this._userService.user = response.user;
// Return a new observable with the response
return of(response);
})
);
When I checked, I noticed that XSRF-TOKEN cookies are returned at the time of the first request, but they are not saved in the browser
There is a point that if I call the API directly and not with Ajax, this token is saved in the browser.
After this, the tokens will be stored in the cookie, but the XSRF-TOKEN will not be sent in the request
I was able to solve my problem Of course, I came to the conclusion that I didn't need to use antiforgy because I had jwt
Antiforgery token protects from CSRF attacks, which are based on cookies.
As long as your JWT is manually attached to the selected requests (unlike cookies that are attached to every request in the browser) the CSRF is not possible anymore.
So, the answer is: it is correct for the tokens that are not sent in cookies.
But I will write the solution I found I added withCredentials:true to my request and then the cookies were saved
return this._httpClient.post(environment.authUrl+ 'api/Account/login',credentials,{headers: headers , withCredentials:true }).pipe(
switchMap((response: any) => {
return of(response);
})
);
Of course, because I was using Identity, I also changed the Antiforge token generation method on the server
public void RegenerateAntiForgeryCookies(IEnumerable<Claim> claims)
{
var httpContext = _contextAccessor.HttpContext;
if (httpContext is null)
{
throw new InvalidOperationException("httpContext is null");
}
httpContext.User = new ClaimsPrincipal(new ClaimsIdentity(claims, JwtBearerDefaults.AuthenticationScheme));
var tokens = _antiforgery.GetAndStoreTokens(httpContext);
if (tokens.RequestToken is null)
{
throw new InvalidOperationException("tokens.RequestToken is null");
}
httpContext.Response.Cookies.Append(
XsrfTokenKey,
tokens.RequestToken,
new CookieOptions
{
HttpOnly = false // Now JavaScript is able to read the cookie
});
}