3

Ich habe eine benutzerdefinierte IConfigurationDbContext erstellt, um IDS4 mit Oracle zu verwenden.mit IdentityServer4 mit benutzerdefinierter Konfiguration DBContext

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>(); 

Ich habe auch meine Gewohnheit IClientStore, die an dem Behälter wie folgt hinzugefügt:

services.AddScoped<IClientStore, ClientStore>(); 

wenn ich IdentityConfigurationDbContext Migration laufen lasse, erhalte ich diese Fehlermeldung:

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

Ich habe versucht, dies zu tun:

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

Ist dies der richtige Weg, um eine benutzerdefinierte DbContext mit IDS4 zu benutzen? und wie behebe ich dieses Problem und schließe meine Migration ab?

Antwort

2

Ich habe einen anderen Ansatz versucht. Statt IConfigurationDbContext die Implementierung habe ich geerbt von 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); 
     } 
    } 
} 

Und in dem 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>(); 

Es funktioniert wie ein Charme. Disclaimer: das ist nicht meine Idee. Ich kann mich einfach nicht an die Quelle erinnern.

+0

ich das tat, aber habe diesen Fehler während der Migration: kein parameterlosen Konstruktor wurde auf ‚IdentityConfigurationDbContext‘ gefunden. Fügen Sie entweder einen parameterlosen Konstruktor zu 'IdentityConfigurationDbContext' hinzu oder fügen Sie eine Implementierung von 'IDbContextFactory ' in derselben Assembly wie 'IdentityConfigurationDbContext' hinzu. – capiono

+0

obwohl Sie geerbt von ** ConfigurationDbContext ** – MJK

+0

Ja, ich habe auch eine No parameterless Konstruktor gleichen Sache. – capiono

0

Durch Hinzufügen eines IDbContextFactory wurde das Problem behoben.

public class IdentityConfigurationDbContextFactory : IDbContextFactory<IdentityConfigurationDbContext> { 

     public IdentityConfigurationDbContext Create(DbContextFactoryOptions options) { 
      var optionsBuilder = new DbContextOptionsBuilder<ConfigurationDbContext>(); 
      var config = new ConfigurationBuilder() 
          .SetBasePath(options.ContentRootPath) 
          .AddJsonFile("appsettings.json") 
           .AddJsonFile($"appsettings.{options.EnvironmentName}.json", true) 

          .Build(); 

      optionsBuilder.UseOracle(config.GetConnectionString("DefaultConnection")); 

      return new IdentityConfigurationDbContext(optionsBuilder.Options, new ConfigurationStoreOptions()); 
     } 
    } 
+0

Oh ja, Sie sollten eine Implementierung von 'IDbContextFactory haben' – MJK

+0

Wie haben Sie den CustomConfigurationDbContext in Startup.cs registriert? Ich erhalte diesen Fehler System.InvalidOperationException: 'Es wurde kein Dienst für den Typ' CustomConfigurationDbContext 'registriert.' – capiono

+0

Überprüfen Sie meine Antwort [oben] (https://stackoverflow.com/questions/44618235/using-identityserver4-with-custom-configration-dbcontext/44627356#44627356), das ist das einzige Zeug, das ich beim Start hinzugefügt habe – MJK

0

Mit der neuesten Version unterstützt das Identityserver-Framework benutzerdefinierte Implementierung von Konfigurationsspeicher, Operationsspeicher.

siehe unten zum Beispiel

public class CustomPersistsDbContext : DbContext, IPersistedGrantDbContext 
    { 
    } 

Auf dem Startdienst

.AddOperationalStore<CustomPersistsDbContext>(options => 
Verwandte Themen