在不同 API 的 IndetityServer4 中使用 ConfigurationDbContext

Use of ConfigurationDbContext in IndetityServer4 from different API's

在将 UserManager 添加到不初始化 IdentityServer4 的 API () 中解决了我最初的问题之后(后者又在仅负责用户注册和登录的 Web 应用程序中初始化) ) 我有 运行 另一个问题。从同一个 API 我还希望从 IdentityServer4 的 IConfigurationDbContext 中获取客户端和资源。

到目前为止我正在尝试的是: 我在 API 的启动中添加 ConfigurationDbContext,然后通过 ClientsController 和 ClientsRepository 我试图访问客户端,如下所示。

Startup.cs

 services.AddDbContext<ApplicationDbContext>(options =>
        options.UseNpgsql(defaultConnection, db => db.MigrationsAssembly("XXXXXXX"))
    );

 services.AddDbContext<ConfigurationDbContext>(options =>
        options.UseNpgsql(defaultConnection, db => db.MigrationsAssembly("XXXXXXXX"))
    );

  services.AddIdentityCore<ApplicationUser>(options => {
        options.Password.RequireNonAlphanumeric = false;
    });
    new IdentityBuilder(typeof(ApplicationUser), typeof(IdentityRole), services)
        .AddRoleManager<RoleManager<IdentityRole>>()
        .AddSignInManager<SignInManager<ApplicationUser>>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

ClientsRepository.cs(在 .DataAccess 中):

private readonly IConfigurationDbContext _context;
public bool AutoSaveChanges { get; set; } = true;

public ClientRepository(IConfigurationDbContext context)
{
    _context = context;
}

public Task<Client> GetClientAsync(int id)
{
    return _context.Clients
        .Include(x => x.AllowedGrantTypes)
        .Include(x => x.RedirectUris)
        .Include(x => x.PostLogoutRedirectUris)
        .Include(x => x.AllowedScopes)
        .Include(x => x.ClientSecrets)
        .Include(x => x.Claims)
        .Include(x => x.IdentityProviderRestrictions)
        .Include(x => x.AllowedCorsOrigins)
        .Include(x => x.Properties)
        .Where(x => x.Id == id)
            .SingleOrDefaultAsync();
 }

但是,我收到以下错误:

System.InvalidOperationException: Unable to resolve service for type 'IdentityServer4.EntityFramework.Interfaces.IConfigurationDbContext' while attempting to activate 'XXXXXX.Data.Repositories.ClientRepository'. 

我猜它又与服务启动有关,但我似乎找不到它。

有没有人解决过类似的问题?

最好的, 马里奥.

如果您想使用 ServicesCollection 包中已有的 ServicesCollection 扩展,请使用这些扩展:

        services.AddConfigurationStore(options =>
        {
            options.ConfigureDbContext = builder => builder.UseNpgsql(defaultConnection, db => db.MigrationsAssembly("XXXXXXXX"));
        });

这将为您添加 IConfigurationDbContext 以便以后可以通过 DI 在其他服务中使用它。

如果要将其直接添加到ServicesCollection,请使用以下静态方法:

    public static IServiceCollection AddConfigurationStore(this IServiceCollection services,
        Action<ConfigurationStoreOptions> storeOptionsAction = null)
    {
        return services.AddConfigurationStore<ConfigurationDbContext>(storeOptionsAction);
    }

    public static IServiceCollection AddConfigurationStore<TContext>(this IServiceCollection services,
    Action<ConfigurationStoreOptions> storeOptionsAction = null)
    where TContext : DbContext, IConfigurationDbContext
    {
        var options = new ConfigurationStoreOptions();
        services.AddSingleton(options);
        storeOptionsAction?.Invoke(options);

        if (options.ResolveDbContextOptions != null)
        {
            services.AddDbContext<TContext>(options.ResolveDbContextOptions);
        }
        else
        {
            services.AddDbContext<TContext>(dbCtxBuilder =>
            {
                options.ConfigureDbContext?.Invoke(dbCtxBuilder);
            });
        }
        services.AddScoped<IConfigurationDbContext, TContext>();

        return services;
    }