Rock Man

Welcome to the blog of identityserver.com hosted by Rock Solid Knowledge, the IdentityServer European Partners, offering commercial support, consultancy and training for IdentityServer 3 & 4, and all things authentication, backed by the creators of IdentityServer themselves.

Extending the AdminUI Schema

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...

Extending the AdminUI Schema
Scott Brady Wednesday, 22 August, 2018

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<IdentityExpressUser, IdentityExpressRole>()
    .AddEntityFrameworkStores<IdentityExpressDbContext>();

services.AddDbContext<IdentityExpressDbContext>(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<ExtendedUser> 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<ExtendedUser> {
    public ExtendedDbContext(DbContextOptions<ExtendedDbContext> options) : base(options) { }

    public DbSet<Department> Departments { get; set; }

    protected override void OnModelCreating(ModelBuilder builder) {
        base.OnModelCreating(builder);

        builder.Entity<Department>(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<ExtendedUser, IdentityExpressRole>()
    .AddEntityFrameworkStores<ExtendedDbContext>();

services.AddDbContext<ExtendedDbContext>(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.

Rock Solid Knowledge

Rock Solid Knowledge are the European commercial partners for IdentityServer, offering custom development, consultancy, training and commercial support contracts. Get in contact for more details and to discuss your requirements at identityserver.com.

comments powered by Disqus