Sunday, February 19, 2023

How to connect ASP.NET Core 6 API with React JS using Windows Authentication

 Recently I had to setup ReactJs application to support Windows Authentication with ASP.NET Core 6 API. Authorization will be handled via LDAP which is not included in this post.

I'm using axios as the http client to query API. Let's start creating a simple ReactJs Application.

Step 01 - Create React SPA.

npx create-react-app react-app-with-windows-auth
cd react-app-with-windows-auth
npm start

Refer Getting Started Guide for more information.

Step 02 - Setup axios

Axios is a promise-based HTTP Client for node.js and the browser. It is isomorphic (= it can run in the browser and nodejs with the same codebase). On the server-side it uses the native node.js http module, while on the client (browser) it uses XMLHttpRequests. Refer Getting Started for more information

npm install axios

Step 03 - Create ASP.NET Core 6 API Project

dotnet new webapi -o TodoApi
cd TodoApi

Step 04 - Add windows authentication to 6 API Project

in launchSettings.json file add following settings.

"iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": false,
  }

Step 05 - Add CORS for Web Api Project

in Program.cs file add following settings.

using Microsoft.AspNetCore.Authentication.Negotiate;

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    ContentRootPath = Directory.GetCurrentDirectory()
});

builder.Services.AddHttpContextAccessor();
builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(
        policy =>
        {
            policy
                    .WithOrigins("http://localhost:44426") // ReactApp Url
                    .AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowCredentials();
        });
});

// Add services to the container.

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddControllersWithViews();

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
   .AddNegotiate();

builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = options.DefaultPolicy;
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment() || app.Environment.IsProduction())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseStaticFiles();
app.UseRouting();

app.UseCors();

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

app.MapControllerRoute(
    name: "default",
    pattern: "{controller}/{action=Index}/{id?}").RequireAuthorization();

app.MapFallbackToFile("index.html");

app.Run();

Step 06 - Add Axios settings

 async populateWeatherData() {

        try {
            const response = await axios.get('http://localhost:5000/weatherforecast/GetWeatherForecast', { withCredentials: true });
            console.log(response);
            this.setState({ forecasts: response.data, loading: false });
        } catch (error) {
            console.error(error);
        }
    }

Step 07 - Run both React App and Backend API

It will prompt small window to enter windows login and password when you try to access api endpoints. You can observe the same popup when you run swagger endpoint too

Step 08 - Working solution can be found in my git account

No comments:

Post a Comment