Back to: ASP.NET Core Identity Tutorials
Customizing ASP.NET Core Identity Database Tables
In this article, I will discuss Customizing ASP.NET Core Identity Database Tables. Please read our previous article discussing UserManager, SignInManager, and RoleManager Classes in ASP.NET Core Identity. ASP.NET Core Identity is a powerful and flexible framework that handles authentication and authorization in ASP.NET Core applications. However, the default Identity schema may not always fit your application’s needs perfectly. Customizing Identity tables lets you design user and role management to meet your business requirements.
Why Customize ASP.NET Core Identity Database?
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:
- Additional user details (first name, last name, date of birth, last login time, etc.)
- Extended role information (description, active status)
- Relationships with other entities (such as linking an address to a user)
- Customized table names and schema to fit your project or organization’s standards
Customizing Identity lets you shape the system to meet your business requirements perfectly.
How to Customize ASP.NET Core Identity Tables?
We need to follow the steps below:
- Create a Custom User Class: Inherit from IdentityUser (or IdentityUser<TKey>) and add your properties (e.g., FirstName, LastName).
- Create a Custom Role Class: Inherit from IdentityRole (or IdentityRole<TKey>) and add your properties (e.g., Description).
- Create Any Additional Entities: For example, create an Address class if you want to link addresses to users.
- Update Your DbContext: Inherit from IdentityDbContext<YourUser, YourRole, TKey>, add DbSet for your new entities, and configure relationships and table names in OnModelCreating.
- Register Identity with Custom Types: In Program.cs class file, use AddIdentity<YourUser, YourRole>() and AddEntityFrameworkStores<YourDbContext>().
- Run Migrations and Update the Database: Use EF Core migrations to create/update your database schema.
Example Scenario: Customizing ASP.NET Core Identity Tables
We are building a real-world ASP.NET Core MVC application that requires a robust user authentication and authorization system. However, the default Identity setup is too basic for our needs. Our application demands:
- Richer user profiles (including first name, last name, date of birth, last login timestamp, active status, and audit fields).
- Enhanced role management (adding descriptions, active status, and audit tracking).
- Storing user addresses in a related entity with a strict one-to-one relationship.
- Renaming default Identity tables to fit your existing database naming conventions better.
- Seeding initial roles with metadata and consistent GUID keys.
Extending IdentityUser
The base IdentityUser class uses a string as its primary key and contains basic properties. To extend it:
- You derive your own class from IdentityUser<Guid> to use Guid as the primary key type (better for uniqueness and database efficiency).
- You add extra properties like FirstName, LastName, DateOfBirth, and audit fields (CreatedOn, ModifiedOn).
- You add a navigation property for the related Address entity to represent a one-to-one relationship.
This makes the user model richer and aligned with your domain data. So, create a class file named ApplicationUser.cs within the Models folder and then copy and paste the following code:
using Microsoft.AspNetCore.Identity; namespace ASPNETCoreIdentityDemo.Models { public class ApplicationUser : IdentityUser<Guid> { // Extended properties public string FirstName { get; set; } = null!; public string? LastName { get; set; } public DateTime? DateOfBirth { get; set; } public DateTime? LastLogin { get; set; } public bool IsActive { get; set; } //Audit Columns public DateTime? CreatedOn { get; set; } public DateTime? ModifiedOn { get; set; } // Navigation property for one-to-many relationsip public virtual List<Address>? Addresses { get; set; } } }
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.
- IsActive — to mark whether the role is active or deprecated.
- Audit fields (CreatedOn, ModifiedOn) — helpful in tracking changes over time.
This allows enhanced role management tailored to your application. So, create a class file named ApplicationRole.cs within the Models folder and then copy and paste the following code:
using Microsoft.AspNetCore.Identity; namespace ASPNETCoreIdentityDemo.Models { public class ApplicationRole : IdentityRole<Guid> { // Extended property public string? Description { get; set; } public bool IsActive { get; set; } //Audit Columns public DateTime? CreatedOn { get; set; } public DateTime? ModifiedOn { get; set; } } }
Add Address Entity
Since users usually have an address, you create a new Address class representing user addresses. The class includes:
- A Guid primary key (Id).
- A foreign key, UserId, links back to the user.
- Address fields like Street, City, State, Postal Code, and Country.
- IsActive and audit columns to manage state and track history.
This entity forms a one-to-many relationship with ApplicationUser, i.e., one user can have multiple addresses. So, create a class file named Address.cs within the Models folder and then copy and paste the following code.
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASPNETCoreIdentityDemo.Models { public class Address { public Guid Id { get; set; } // FK to ApplicationUser [Required] public Guid UserId { get; set; } [ForeignKey(nameof(UserId))] public virtual ApplicationUser User { get; set; } = null!; public string Street { get; set; } = null!; public string City { get; set; } = null!; public string State { get; set; } = null!; public string PostalCode { get; set; } = null!; public string Country { get; set; } = null!; public bool IsActive { get; set; } //Audit Columns public DateTime? CreatedOn { get; set; } public DateTime? ModifiedOn { get; set; } } }
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, Guid> { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); // Rename tables builder.Entity<ApplicationUser>().ToTable("Users"); builder.Entity<ApplicationRole>().ToTable("Roles"); builder.Entity<IdentityUserRole<Guid>>().ToTable("UserRoles"); builder.Entity<IdentityUserClaim<Guid>>().ToTable("UserClaims"); builder.Entity<IdentityUserLogin<Guid>>().ToTable("UserLogins"); builder.Entity<IdentityRoleClaim<Guid>>().ToTable("RoleClaims"); builder.Entity<IdentityUserToken<Guid>>().ToTable("UserTokens"); // Seed initial roles using HasData var adminRoleId = Guid.Parse("c8d89a25-4b96-4f20-9d79-7f8a54c5213d"); var userRoleId = Guid.Parse("b92f0a3e-573b-4b12-8db1-2ccf6d58a34a"); var managerRoleId = Guid.Parse("d7f4a42e-1c1b-4c9f-8a50-55f6b234e8e2"); var guestRoleId = Guid.Parse("f2e6b8a1-9d43-4a7c-9f32-71d7c5dbe9f0"); builder.Entity<ApplicationRole>().HasData( new ApplicationRole { Id = adminRoleId, Name = "Admin", NormalizedName = "ADMIN", Description = "Administrator role with full permissions.", IsActive = true, CreatedOn = new DateTime(2025, 8, 4), ModifiedOn = new DateTime(2025, 8, 4) }, new ApplicationRole { Id = userRoleId, Name = "User", NormalizedName = "USER", Description = "Standard user role.", IsActive = true, CreatedOn = new DateTime(2025, 8, 4), ModifiedOn = new DateTime(2025, 8, 4) }, new ApplicationRole { Id = managerRoleId, Name = "Manager", NormalizedName = "MANAGER", Description = "Manager role with moderate permissions.", IsActive = true, CreatedOn = new DateTime(2025, 8, 4), ModifiedOn = new DateTime(2025, 8, 4) }, new ApplicationRole { Id = guestRoleId, Name = "Guest", NormalizedName = "GUEST", Description = "Guest role with limited access.", IsActive = true, CreatedOn = new DateTime(2025, 8, 4), ModifiedOn = new DateTime(2025, 8, 4) } ); } public DbSet<Address> Addresses { get; set; } } }
Registering Services in Program.cs:
In the Program class, we need to:
- Register the ApplicationDbContext with SQL Server using the connection string from appsettings.json.
- Add Identity services specifying your custom user and role types.
- Add middleware for authentication and authorization to the request pipeline.
This sets up the application to use your customized Identity model fully integrated with EF Core and SQL Server. So, please modify the Program class file as follows:
using ASPNETCoreIdentityDemo.Data; using ASPNETCoreIdentityDemo.Models; using Microsoft.EntityFrameworkCore; namespace ASPNETCoreIdentityDemo { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); // Register Entity Framework Core with SQL Server builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("SQLServerIdentityConnection"))); // Register ASP.NET Core Identity Services using AddIdentity builder.Services.AddIdentity<ApplicationUser, ApplicationRole>() .AddEntityFrameworkStores<ApplicationDbContext>(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); // Add Authentication and Authorization Middleware app.UseAuthentication(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run(); } } }
Modify AppSettings.json file:
Modify the appsettings.json file as follows. Here, we define a SQL Server connection string named SQLServerIdentityConnection, which points to a local or remote SQL Server instance and specifies the database name (IdentityCoreDB). EF Core uses this connection string to connect and operate on the database.
{ "ConnectionStrings": { "SQLServerIdentityConnection": "Server=LAPTOP-6P5NK25R\\SQLSERVER2022DEV;Database=IdentityCoreDB;Trusted_Connection=True;TrustServerCertificate=True;" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
Update Identity Database Schema
Next, we need to generate the Migration file again and update the database. So, open the Visual Studio Package Manager Console and execute the following Add-Migration and Update-Database commands.
Now, if you verify the database, you should see the following tables in the IdentityCoreDB database.
Customizing ASP.NET Core Identity tables allows us to extend and adapt the built-in authentication and authorization system to fit our application’s specific requirements better. By adding custom user and role properties, defining related entities like addresses, and renaming tables, we create a more organized, flexible, and maintainable identity system. This customization ensures our app can securely manage user data while meeting our business needs effectively.
In the next article, I will discuss How to Implement Register, Login, and Logout in ASP.NET Core Identity. In this article, I explain how to customize ASP.NET Core Identity Database Tables. I hope you enjoy this Customizing ASP.NET Core Identity Database Tables article.
Thanks
Want to master ASP.NET Core Identity?
Check out our latest video: ASP.NET Core Identity Introduction, Setup, and Customization
Learn step-by-step how to set up and customize ASP.NET Core Identity for secure login, role management, and more.
Watch now 👉 https://www.youtube.com/watch?v=WGd9nyoQMjg
Boost your .NET skills with practical, easy-to-follow tutorials from Dot Net Tutorials! Don’t forget to like, share, and subscribe for more .NET tutorials and videos!