Web Kokua Banner Image

ASP.NET Core MVC Identity

The ASP.NET Core Identity is a web application membership management system that provides login functionality and security for a Web Application. It provides the base database tables needed to implement site security.

Implementation Steps

  1. Create a project:
    • ASP.NET Core Web App (Model-View-Controller)
    • Enter a project name
    • Choose a location
    • Select .NET 9.0 (Standard Term Support) as a framework
    • Configure for HTTPS - Checked
    • Do not use top-level statements - Checked
  2. Install NuGet Packages
    • Microsoft.AspNetCore.Identity.EntityFrameworkCore
    • Microsoft.AspNetCore.Identity.UI
    • Microsoft.EntityFrameworkCore.SqlServer
    • Microsoft.EntityFrameworkCore.Tools
  3. Add ApplicationDbContext.cs to Models folder:
    using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; namespace <Project Name Here>.Models { public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } } }
  4. Add a database connection string to the appsettings.json file:
    { "ConnectionStrings": { "DBCS": "Data Source=DBServerName;Initial Catalog=DBName;user id=UserName;password=DBPassword;MultipleActiveResultSets=True;TrustServerCertificate=True" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
  5. Modify the Program.cs file.
    using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using WebKokuaCore.Models; namespace WebKokuaCore { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); var connectionString = builder.Configuration.GetConnectionString("DBCS") ?? throw new InvalidOperationException("Connection string 'DBCS' not found."); builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString)); builder.Services.AddIdentity<IdentityUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); // 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.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapStaticAssets(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}") .WithStaticAssets(); app.Run(); } } }
  6. Make changes to the database by entering the following into the Package Manager Console (Tools>NuGet Package Manager>Package Manager Console)
    PM> Add-Migration IdentityMigration1 ... PM> update-database
  7. The following database tables will be created:
    _EFMigrationsHistory MigrationId nvarchar(150) PK NOT NULL ProductVersion nvarchar(32) NOT NULL AspNetRoleClaims Id int PK NOT NULL RoleId nvarchar(450) FK NOT NULL ClaimType nvarchar(max) NULL ClaimValue nvarchar(max) NULL AspNetRoles Id nvarchar(450) PK NOT NULL Name nvarchar(256) NULL NormalizedName nvarchar(256) NULL ConcurrencyStamp nvarchar(max) NULL AspNetUserClaims Id int PK NOT NULL UserId nvarchar(450) FK NOT NULL ClaimType nvarchar(max) NULL ClaimValue nvarchar(max) NULL AspNetUserLogins LoginProvider nvarchar(450) PK NOT NULL ProviderKey nvarchar(450) PK NOT NULL ProviderDisplayName nvarchar(max) NULL UserId nvarchar(450) FK NOT NULL AspNetUserRoles UserId nvarchar(450) FK NOT NULL RoleId nvarchar(450) FK NOT NULL AspNetUsers Id nvarchar(450) PK NOT NULL UserName nvarchar(256) NULL NormalizedUserName nvarchar(256) NULL Email nvarchar(256) NULL NormalizedEmail nvarchar(256) NULL EmailConfirmed bit NOT NULL PasswordHash nvarchar(max) NULL SecurityStamp nvarchar(max) NULL ConcurrencyStamp nvarchar(max) NULL PhoneNumber nvarchar(max) NULL PhoneNumberConfirmed bit NOT NULL TwoFactorEnabled bit NOT NULL LockoutEnd datetimeoffset(7) NULL LockoutEnabled bit NOT NULL AccessFailedCount int NOT NULL AspNetUserTokens UserId nvarchar(450) FK NOT NULL LoginProvider nvarchar(450) NOT NULL Name nvarchar(450) NOT NULL Value nvarchar(max) NULL

Identity Table Descriptions

The following are the Identity tables created and what their columns represent.


AspNetUsers Table

The columns in the AspNetUsers table generally include the following:


AspNetRoles Table

The columns in the AspNetRoles table generally include the following:


AspNetUserRoles Table

The columns in the AspNetUserRoles table generally include the following:


AspNetUserClaims Table

The columns in the AspNetUserClaims table generally include the following:


AspNetUserLogins Table

The columns in the AspNetUserLogins table generally include the following:


AspNetUserTokens Table

The columns in the AspNetUserTokens table generally include the following:


AspNetRoleClaims Table

The columns in the AspNetRoleClaims table generally include the following:


Customizing Database Core Identity Tables

By default, ASP.NET Core Identity provides a ready-to-use user and role system with basic properties like UserName, Email, and PasswordHash. However, most real-world applications need more information and custom features such as:


How to Customize ASP.NET Core Identity Tables?


  1. Extending IdentityUser

    using Microsoft.AspNetCore.Identity; namespace ASPNETCoreIdentityDemo.Models { public class ApplicationUser : IdentityUser { // Extended properties public string? FirstName { get; set; } public string? LastName { get; set; } } }
  2. Extending IdentityRole

    Similarly, the IdentityRole is extended by creating ApplicationRole derived from IdentityRole<Guid>. You add properties like:

    • Description - to describe the role's purpose.
    using Microsoft.AspNetCore.Identity; namespace ASPNETCoreIdentityDemo.Models { public class ApplicationRole : IdentityRole { // Extended property public string? Description { get; set; } } }
  3. Configuring ApplicationDbContext

    Now, we need to customize the ApplicationDbContext class to:

    • Inherit from IdentityDbContext<ApplicationUser, ApplicationRole, Guid>, indicating the use of your custom user and role classes with Guid keys.
    • Rename the default Identity tables to your preferred names (Users, Roles, UserRoles, etc.) using Fluent API in OnModelCreating. This helps maintain a clean and consistent database naming.
    • Seed initial roles with fixed GUIDs and additional metadata using HasData for automatic insertion during migration.

    So, please modify the ApplicationDbContext class as follows:

    using ASPNETCoreIdentityDemo.Models; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; namespace ASPNETCoreIdentityDemo.Data { public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string> { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.Entity<IdentityUserRole<string>>() .HasOne<ApplicationRole>() .WithMany() .HasForeignKey(ur => ur.RoleId) .OnDelete(DeleteBehavior.NoAction); } } }
  4. Make Changes in Program.cs

    Change IdentityUser to ApplicationUser, and change IdentityRole to Application Role

    builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString)); builder.Services.AddIdentity<ApplicationUser, ApplicationRole>() .AddEntityFrameworkStores<ApplicationDbContext>();
  5. Make changes to the database by entering the following into the Package Manager Console (Tools>NuGet Package Manager>Package Manager Console)
    PM> Add-Migration IdentityMigration2 ... PM> update-database

Registering A New User