【问题标题】:Use of ConfigurationDbContext in IndetityServer4 from different API's在不同 API 的 IdentityServer4 中使用 ConfigurationDbContext
【发布时间】:2019-07-02 14:26:15
【问题描述】:

在将 UserManager 添加到不初始化 IdentityServer4 的 API (User creation with IdentityServer4 from multiple API's) 解决了我的初始问题之后(它又在仅负责用户注册和登录的 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'. 

我猜它必须再次对服务启动做一些事情,但我似乎找不到它。

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

最好, 马里奥斯。

【问题讨论】:

    标签: c# asp.net-core asp.net-identity identityserver4


    【解决方案1】:

    如果您想使用这些扩展,只需使用 IDS4.EFCore 包中已有的 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;
        }
    

    【讨论】:

    • 我没有任何方法AddConfigurationDbContext,你确定是这样吗?正如您在我的启动中看到的那样,我将 AddDbContext 与 ConfigurationDbContext 一起使用,但它似乎没有起到作用。
    • @Davelis4 ConfiguratonDbContext 在哪里声明?我的意思是哪个程序集。另外,我已经编辑了答案,我的方法名称有点错误。毕竟是AddConfigurationStore
    • ConfigurationDbContext 的声明与我之前在 WebApp 中的问题中一样,而不是在我试图从中访问它的 API 中。此外,AddConfigurationStore 抛出以下内容:IServiceCollection 不包含...的定义,并且最佳扩展方法重载 IdentityServerEntityFrameworkBuilderExtensions.AddConfigurationStore(...) 需要类型为“IIdentityServerBuilder;”的接收器
    • @Davelis4 好吧,我给了你更多代码来直接使用ServicesCollection 进行这项工作。创建一些扩展类来保存这些静态方法。
    • @Davelis4 是的,这也适用于通过上下文查询 api 资源。为了回答你的另一个问题,你的这个版本不起作用,因为你添加了一个具体类型的 ConfigurationDbContext 但是你试图在你的控制器中使用接口版本。
    猜你喜欢
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-28
    • 1970-01-01
    • 2019-05-08
    • 2018-12-06
    • 1970-01-01
    相关资源
    最近更新 更多