ASP.NET Core 6 React app with Individual accounts using SQLite 401 Unauthorized error

Viewed 103

I've created a DEFAULT ASP.NET Core 6 React app with Individual Accounts enabled and SQLite as the default database:

dotnet new react -au Individual -o core-react-sqlite

But then when I run the app, register a new user, confirm the user, login, navigate to "Fetch data" (https://localhost:44480/fetch-data) I get a 401 Unauthorized error:

enter image description here

Any ideas why?

I've checked the docs (here, here, and here) but it doesn't say much about authorization when using React or maybe I'm just reading it wrong?

Here's my Program.cs (default):

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.EntityFrameworkCore;
using core_react_sqlite.Data;
using core_react_sqlite.Models;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.AddIdentityServer()
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

builder.Services.AddAuthentication()
    .AddIdentityServerJwt();

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

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

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

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

app.MapFallbackToFile("index.html");;

app.Run();
2 Answers

In the configuration for AddJwtBearer in the API, you can set the following flag to true:

.AddJwtBearer(opt =>
{
     opt.IncludeErrorDetails = true;
     ...

If you do this, then you will get an extra header in the 401 error response that can give you some clues why the request failed:

HTTP/1.1 401 Unauthorized
Date: Sun, 02 Aug 2020 11:19:06 GMT
WWW-Authenticate: Bearer error="invalid_token", error_description="The signature is invalid"

After a lot of reading I've learned that in 99% of all cases you should opt for a managed identity provider.

In my case I went with Azure AD B2C since it's the most generous, I already have the rest of my infrastructure on Azure, and docs seem ok.

Related