AdminUI uses a custom ASP.NET Core Identity schema that extends the default user entities, allowing existing IdentityServer solutions to continue using these entities...
Our IdentityServer4 administration tool, AdminUI, uses a custom ASP.NET Core Identity schema that extends the default user entities such as IdentityUser
and IdentityRole
. This allows existing IdentityServer solutions to initially continue using these base entities while still taking advantage of AdminUI’s user administration features. We recommend eventually updating existing applications to use our custom schema.
One common question we get asked is: “How can I extend the AdminUI schema?”. While changes to the schema won’t be reflected within AdminUI, there is still a use case for doing this, especially if the existing solution already extended the schema.
Note that while you can extend the schema, you won’t be able to add required fields to the existing AdminUI tables; otherwise, AdminUI will not be able to create new records.
Configuring your Schema
To start extending the AdminUI schema, you’ll first need the schema itself. This is available on nuget in the IdentityExpress.Identity library.
install-package IdentityExpress.Identity -pre
You’ll then need to register the schema user types in your application and the various ASP.NET Core Identity services you’ll want to use:
services.AddIdentity()
.AddEntityFrameworkStores();
services.AddDbContext(builder);
Why IdentityExpress?
AdminUI started off as part of a larger project called IdentityExpress; however, we decided to release AdminUI early, as a separate product. Work on IdentityExpress is still continuing in our Bristol office and we hope to announce something in the future.
Extending the model
Now that you have the schema you can extend it. For this example, let’s extend the user type, by creating a new user type that extends IdentityExpressUser
. So, let’s add a new entity called department and allow a department to contain many users. In the user, both a navigation property and the department ID will be used. The foreign key on the user must be a nullable type.
public class ExtendedUser : IdentityExpressUser {
public int? DepartmentId { get; set; }
public virtual Department Department { get; set; }
}
public class Department {
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection Users { get; set; }
}
Now that you have an extended user, you now need to create a DbContext
that is aware of this user and configure it accordingly. If you are making changes to one of the existing entities, ensure that you call the base implementation of OnModelCreating
before your customizations.
public class ExtendedDbContext : IdentityExpressDbContext {
public ExtendedDbContext(DbContextOptions options) : base(options) { }
public DbSet Departments { get; set; }
protected override void OnModelCreating(ModelBuilder builder) {
base.OnModelCreating(builder);
builder.Entity(dept =>
{
dept.HasKey(x => x.Id);
dept.ToTable("Departments");
dept.HasMany(x => x.Users)
.WithOne(x => x.Department)
.HasForeignKey(x => x.DepartmentId)
.IsRequired(false);
});
}
}
You then need to update your ConfigureServices
registrations to use our new user entity, and our new DbContext
:
services.AddIdentity()
.AddEntityFrameworkStores();
services.AddDbContext(builder);
Configuring AdminUI
When you are using a custom schema for AdminUI, Entity Framework migrations will from then on need to be managed by your applications, since AdminUI itself will only know about the base schema.
This means you’ll need to tell AdminUI to not handle migrations for that database, which you can do by setting the API configuration variable of RunIdentityMigrations
to false
.
Source Code
You can find a bare-bones application configured with the above code on GitHub.
Let us know if you have any questions or issues, we’re always looking for ways to improve the AdminUI product.