Basic Auth JWT with Core for SPAs
So, do you want to quickly create a POC (proof of concept) or want to just try out some silly thoughts? Well, you are in the correct place!
These are the steps to quickly implement authentication and authorization to your API project! You can also download the template at the end of this page as well! It is on the Core 8 version 👌
Required NuGet packages
Let's start by installing the NuGet packages. We need at least:
NuGet\Install-Package Microsoft.AspNetCore.Identity.EntityFrameworkCore -Version 8.0.2
One of these for our database:
NuGet\Install-Package Microsoft.EntityFrameworkCore.InMemory -Version 8.0.2
NuGet\Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 8.0.2
NuGet\Install-Package Microsoft.EntityFrameworkCore.Sqlite -Version 8.0.2
Always good to have:
Microsoft.EntityFrameworkCore.Tools
Now let's move to our Program.cs class. We are going to add some services, not so many as you may think. Core 8 makes it very simple to get up and running in no time!
Adding services
We start by adding these:
builder.Services.AddIdentityApiEndpoints<IdentityUser>()
  .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddAuthorization();
right after the var builder = WebApplication.CreateBuilder(args);
It might be a POC or a "silly" app (if such a thing exists!) but let's get into the habit of never forgetting our CORS policy:
builder.Services.AddCors(options =>
{
  options.AddDefaultPolicy(
    builder => builder
    .AllowAnyOrigin()
    .AllowAnyMethod()
    .AllowAnyHeader());
});
obviously, you need to adjust the CORS for your needs! Especially before production!
Now let's add our database:
For InMemory database, you can add the below. Just remember, it "resets" every time you run the application.
builder.Services.AddDbContext<ApplicationDbContext>(
  options => options.UseInMemoryDatabase("AuthDb"));
If you are tired of registering all the time, you can use the below:
// SQL or other databases
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
  options.UseSqlServer(connectionString));
Extend the user
Now, if you need to extend the user, you can create one derived from IdentityUser and use the below:
builder.Services.AddIdentityCore<MyUser>()
 .AddEntityFrameworkStores<AppDbContext>()
 .AddApiEndpoints();
In the above lines, I assume that the MyUser is a class derived from the IdentityUser. Please use a better name than me 🤣
If you are like me and getting really bored when you have to include the credentials with every call when you have to test more than one endpoint, I would suggest doing the below.
Swagger configuration
This is how you could tell Swagger to remember you for a little bit!
// basic auth with the swagger interface for easy testing!
builder.Services.AddSwaggerGen(option =>
{
  option.SwaggerDoc("v1", new OpenApiInfo { Title = "Francophonix API", Version = "v1" });
  option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
  {
    In = ParameterLocation.Header,
    Description = "Please enter a valid token",
    Name = "Authorization",
    Type = SecuritySchemeType.Http,
    BearerFormat = "JWT",
    Scheme = "Bearer"
  });
  option.AddSecurityRequirement(new OpenApiSecurityRequirement
  {
    {
      new OpenApiSecurityScheme
      {
        Reference = new OpenApiReference
        {
          Type=ReferenceType.SecurityScheme,
          Id="Bearer"
        }
      },
      new string[]{}
    }
  });
});
Middlewares for building the application
Now that we added the services, we need to let the framework know about them and include them in the build.
We start by adding the CORS and we map the identity API:
app.UseCors();
app.MapIdentityApi<IdentityUser>();
It's always good to have routing, remember to add it after redirection and before the authorization
app.UseRouting();
 and voila! This is it! Easy peasy! Just run the application, register, log in, and copy the Bearer token into the Autorize at the top right corner before the first endpoint. You are ready to use any endpoints you may have added that are protected with [Authorize] !!!
Â
ConnectionString if you need it!
"ConnectionStrings": {
"DefaultConnection": "Server=XXX.XXX.XX.XX\\SQLEXPRESS; Initial Catalog=XYZ;user id=XYZ;password=XYZ;Trusted_Connection=false;MultipleActiveResultSets=true;TrustServerCertificate=True"
},
(replace X,Y,Z with yours)
Files you can download: