BASKA
BASKA

Reputation: 399

ajax Post request with antiforgerytoken on .net core 2.2

I have a web project using ASP .Net Core 2.2 that has anti-forgery token validation. After that all my AJAX post requests are not working. Is there any way to execute this AJAX request with minimal changes?

$.ajax({
  type: 'POST',
  url: 'Register/RegisterNewUser',
  data: {
    Name: "John",
    Surname: "Doe",
    Email: "[email protected]"
  },
  success: success,
  error: function(xhr, textStatus, errorThrown) {
    alert(errorThrown);
  }
});

Upvotes: 0

Views: 2152

Answers (3)

GTRekter
GTRekter

Reputation: 1007

First, you need to configure the Middleware

TestMiddleware.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;

namespace Test.Middleware
{
    public class TestMiddleware
    {
        private readonly RequestDelegate _next;
        public TestMiddleware(RequestDelegate next)
        {
            _next = next;
        }
        public async Task InvokeAsync(HttpContext httpContext, AppDbContext dataContext, UserManager<User> userManager, IAntiforgery antiforgery)
        {
            SetAntiForgeryTokenCookie();
            // Move forward into the pipeline
            await _next(httpContext);
        }
        private void SetAntiForgeryTokenCookie(HttpContext httpContext, IAntiforgery antiforgery)
        {
            var tokens = antiforgery.GetAndStoreTokens(httpContext);
            httpContext.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
        }
    }
    public static class TestMiddlewareExtensions
    {
        public static IApplicationBuilder UseTestMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<TestMiddleware>();
        }
    }
    #endregion
}

Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Test.Middleware;

namespace Test
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();

            services.AddDbContext<AppDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("Database"), b => b.MigrationsAssembly("Test")));

            services.AddIdentity<User, Role>()
                .AddEntityFrameworkStores<AppDbContext>()
                .AddDefaultTokenProviders();

            services.Configure<IdentityOptions>(options =>
            {
                // Password settings
                options.Password.RequireDigit = true;
                options.Password.RequiredLength = 8;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = true;
                options.Password.RequireLowercase = false;
                options.Password.RequiredUniqueChars = 6;
                // Lockout settings
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
                options.Lockout.MaxFailedAccessAttempts = 10;
                options.Lockout.AllowedForNewUsers = true;
                // User settings
                options.User.RequireUniqueEmail = true;
            });
            services.ConfigureApplicationCookie(options =>
            {
                // Cookie settings
                options.Cookie.HttpOnly = true;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(480);
                options.LoginPath = "/Account/Login";
                options.AccessDeniedPath = "/Account/AccessDenied";
                options.SlidingExpiration = true;
            });
            services.AddAntiforgery(options =>
            {
                // Antiforgety settings
                options.HeaderName = "X-CSRF-TOKEN";
            });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IAntiforgery antiforgery)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();

            app.UseTestMiddleware();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

script.js

self.saveSurvey = function (userId) {
        var csrfToken = self.getCookie("CSRF-TOKEN");
        var ajaxUrl = "Account/Save",
            ajaxData = {
                UserId: userId
            };
        $.ajax({
            type: "POST",
            url: ajaxUrl,
            data: JSON.stringify(ajaxData),
            cache: false,
            contentType: "application/json; charset=utf-8",
            dataType: 'json',
            headers: {
                "X-CSRF-TOKEN": csrfToken
            },
            success: function (viewModel) {
                console.log("Eureka!")
            },
            error: function (error) {
                console.log("Not Eureka!")
            }
        });
    };

Upvotes: 0

BASKA
BASKA

Reputation: 399

Solution:

@using Microsoft.AspNetCore.Antiforgery
@inject IAntiforgery Antiforgery
<!---Some content ---->## Heading ##


<script>
$.ajax({
type: 'POST', 
beforeSend: function (request) { request.setRequestHeader("RequestVerificationToken",@Antiforgery.GetTokens(Context).RequestToken);},
url: 'Register/RegisterNewUser',
data: { Name: "John", Surname:"Doe",Email:"[email protected]" },
success: success,
error: function (xhr, textStatus, errorThrown) { alert(errorThrown);}
});
</script>

Upvotes: 0

Rabby Hasan
Rabby Hasan

Reputation: 352

You could post antiforgerytoken validation with header of your request with .net core 2.2

     $.ajax({
                type: 'POST',
                url: 'Register/RegisterNewUser',
                dataType: 'json',
                data: { Name: "John", Surname: "Doe", Email: "[email protected]" },                    
                headers: {
                    RequestVerificationToken:
                        $('input:hidden[name="__RequestVerificationToken"]').val()
                },
                success: success,
                error: function (xhr, textStatus, errorThrown)
                {
                    alert(errorThrown);
                }
            });

Upvotes: 2

Related Questions