Search code examples
c#entity-frameworkasp.net-coreasp.net-identityidentityserver4

using IdentityServer4 with custom Configration DBContext


I created a customized IConfigurationDbContext in order to using IDS4 with Oracle.

  public class IdentityConfigurationDbContext :  DbContext, IConfigurationDbContext {
        private readonly ConfigurationStoreOptions storeOptions;

        public IdentityConfigurationDbContext(DbContextOptions<IdentityServerDbContext> options)
         : base(options) {
    }

    public IdentityConfigurationDbContext(DbContextOptions<ConfigurationDbContext> options, ConfigurationStoreOptions storeOptions)
        : base(options) {
        this.storeOptions = storeOptions ?? throw new ArgumentNullException(nameof(storeOptions));
    }

    public DbSet<Client> Clients { get; set; }
    public DbSet<IdentityResource> IdentityResources { get; set; }
    public DbSet<ApiResource> ApiResources { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder) {
        modelBuilder.ConfigureClientContext(storeOptions);
        modelBuilder.ConfigureResourcesContext(storeOptions);

        base.OnModelCreating(modelBuilder);
    }
  }

in ConfigureService:

 services.AddIdentityServer()
                .AddTemporarySigningCredential()
                .AddAspNetIdentity<ApplicationUser>();

I also have my custom IClientStore which is added to the container like this:

services.AddScoped<IClientStore, ClientStore>();

when I run IdentityConfigurationDbContext migration, I get this error:

System.InvalidOperationException: No database provider has been configured for this DbContext.

I tried doing this:

services.AddDbContext<IdentityConfigurationDbContext>(builder => builder.UseOracle(connectionString, options => {
                options.MigrationsAssembly(migrationsAssembly);
                options.MigrationsHistoryTable("EF_MIGRATION_HISTORY");
            }));

Is this the right way to use a custom dbcontext with IDS4? and How do I fix this issue, and complete my migration work?


Solution

  • I've tried a different approach. Instead of implementing IConfigurationDbContext I have inherited from IdentityServer4.EntityFramework.DbContexts.ConfigurationDbContext

    public class CustomConfigurationDbContext : ConfigurationDbContext
    {
        public CustomConfigurationDbContext(DbContextOptions<ConfigurationDbContext> options,
            ConfigurationStoreOptions storeOptions)
            : base(options, storeOptions)
        {
        }
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                //...
    
                base.OnConfiguring(optionsBuilder);
            }
        }
    }
    

    And in the startup.cs

    services.AddIdentityServer()
                    .AddTemporarySigningCredential()
                    .AddConfigurationStore(
                        builder => builder.UseSqlServer(connectionString, options => options.MigrationsAssembly(migrationsAssembly)))
                    .AddOperationalStore(
                        builder => builder.UseSqlServer(connectionString, options => options.MigrationsAssembly(migrationsAssembly)))
                    .AddAspNetIdentity<ApplicationUser>();
    

    It works like a charm. Disclaimer: this is not my idea. I just cannot remember the source of that.