Quick Guide to Identity Endpoints in .NET 8+

Ugo UmeokeUgo Umeoke
4 min read

Identity management is a critical aspect of modern web applications, providing the infrastructure necessary for managing users, roles, authentication, and authorization. With .NET 8, Microsoft has further streamlined the process by introducing enhanced Identity APIs that simplify the implementation and management of identity features. This guide will walk you through the process of implementing Identity Management in .NET 8 including user registration, login, and setting up email confirmation as part of the user registration process using the Identity APIs.

What is covered:

  • Setting Up the .NET 8 Web API Project

  • Installing Necessary Packages

  • Configuring Identity and Database Context

  • Running Migrations and Updating the Database

  • Implementing the Email Sender Service

  • Configuring Email Settings

  • Conclusion

Introduction

Implementing identity management in .NET 8 is streamlined with built-in support for authentication and authorization. This article also provide a step-by-step guide to creating identity API endpoints in a .NET 8 Web API application, including a feature for email confirmation during user registration.

Setting Up the .NET 8 Web API Project

dotnet new webapi -n IdentityApiWebApp
cd IdentityApiWebApp

Alternatively, if you are using Rider, click File => New Solution

Installing Necessary Packages

To manage identity in a .NET application, we need several NuGet packages:

  • Microsoft.AspNetCore.Identity.EntityFrameworkCore: Provides identity management functionalities integrated with Entity Framework Core.

  • Microsoft.EntityFrameworkCore.Sqlite: Here we will be using SQLite as the database to keep thing simple.

dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.Tools

Create the User class to inherit IdentityUser

public class User: IdentityUser
{
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
}

This adds two additional fields to the aspnetuser table, FirstName and LastName

Notice that these fields are nullable

Configuring Identity and Database Context

Create a database context class, AppDbContext, to handle your database and Identity setup:

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

public class AppDbContext(DbContextOptions<AppDbContext> option): IdentityDbContext<User>(option)
{
}

Update Program.cs file to configure services for Identity and your dbcontext:

var builder = WebApplication.CreateBuilder(args);

// Authorization
builder.Services.AddAuthorization();

// Configure Identity Database access via EF Core
builder.Services.AddDbContext<AppDbContext>(
    options => options.UseSqlite("DataSource=database.db"));

// Add services for IdentityApi Endpoint and configure the IdentityOptions
builder.Services.AddIdentityApiEndpoints<User>(options =>
{
    options.Password.RequiredLength = 8;
    options.Password.RequireNonAlphanumeric = false;
    options.User.RequireUniqueEmail = true;
    options.SignIn.RequireConfirmedEmail = true;
}).AddEntityFrameworkStores<AppDbContext>();

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
    {
        options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
        {
            In = ParameterLocation.Header,
            Name = "Authorization",
            Type = SecuritySchemeType.ApiKey
        });

        options.OperationFilter<SecurityRequirementsOperationFilter>();
    });

var app = builder.Build();

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

app.UseHttpsRedirection();

app.MapIdentityApi<User>();
app.Run();

Add Migration and Update the Database

dotnet ef migrations add InitialMigration
dotnet ef database update

Now let us Run the App: Either run from your IDE or use the command: dotnet run

Implement the Email Sender Service

This will enable confirmEmail, resendConfirmationEmail and forgotPassword as well as any other use cases in our application

Add a service that implements the interface IEmailSender, you can use any email service of your choice.

In this Guide, MailGun is used to send email. A MailGun account and apiKey is needed to send email. See Get Started with MailGun to register for a free account.

As at the time of writing this, mailgun does not have SDK support for C# so we will fallback to HTTP Api.

public class EmailSender(IConfiguration configuration, ILogger<EmailSender> logger) : IEmailSender
{
}

Add a method SendEmailAsync

public async Task SendEmailAsync(string email, string subject, string htmlMessage)
{
     throw new NotImplementedException();
}

Get your domain, baseUri and apiKey from your configuration file. To keep things simple I am getting it from my appsettings.json but this is not advised, I would suggest you get it from vault, environment variable or any other config file that doesn’t get committed to git.

Inside this method add the following snippets

var baseUri = configuration.GetSection("EmailConfig:BaseUri").Value;
var apiKey = configuration.GetSection("EmailConfig:ApiKey").Value;
var domain = configuration.GetSection("EmailConfig:Domain").Value;
var from = configuration.GetSection("EmailConfig:FromEmail").Value;

Create and Authenticate HttpClient

var client = new HttpClient();
string base64String = Convert.ToBase64String(Encoding.ASCII.GetBytes($"api:{apiKey}"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64String);

Configure and send the http request

var domainBaseUri = string.Format(baseUri, domain);
var postData = new MultipartFormDataContent();
postData.Add(new StringContent(from), "from");
postData.Add(new StringContent(email), "to[0]");
postData.Add(new StringContent(subject), "subject");
postData.Add(new StringContent(htmlMessage), "html");
using HttpResponseMessage request = await client.PostAsync(domainBaseUri, postData);
var response = await request.Content.ReadAsStringAsync();

Register the Service as Singleton or Transient

builder.Services.AddSingleton<IEmailSender, EmailSender>();

Now when a new user signs up they should receive a confirm email message such as below.

Conclusion

Implementing Identity Management in .NET 8 using the Identity APIs is straightforward and powerful, providing everything needed to manage users, roles, authentication, and authorization in your web application. By following this guide, you can set up a secure identity management system that leverages the latest features in .NET 8, ensuring your application is both secure and scalable.

I will be uploading a video tutorial where I performed and explained these in details on my youtube channel, please subscribe and watch out.

0
Subscribe to my newsletter

Read articles from Ugo Umeoke directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ugo Umeoke
Ugo Umeoke