通过不同API在IndetityServer4中使用ConfigurationDbContext

时间:2019-02-08 10:50:34

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

在解决了将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'. 

我猜测它必须再次与Startup服务一起工作,但我似乎找不到它。

有人解决过类似的事情吗?

最好, 马里奥斯。

1 个答案:

答案 0 :(得分:3)

如果要使用这些扩展名,请仅使用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;
    }