angularasp.net-coreantiforgerytoken

angular not sending antiforgytoken


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 response header

storage

There is a point that if I call the API directly and not with Ajax, this token is saved in the browser. stroge after call in browser

After this, the tokens will be stored in the cookie, but the XSRF-TOKEN will not be sent in the request

reqest header


Solution

  • 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
                });
        }