在 ASP.NET Core 8 新核心 Identity 中获取 RoleManager 实例

问题描述 投票:0回答:1

我正在 ASP.NET Web API 应用程序中试验新的身份基础架构(按照 https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization?view =aspnetcore-8.0).

在启动时,一旦构建了

WebApplication
并在运行它之前,我想获取
UserManager<AppUser>
的实例(其中
AppUser
只是从
IdentityUser
派生的类)和
RoleManager<IdentityRole>
,以便我可以播种一些预设的用户帐户。

AFAIK,在启动时播种数据的正确方法是为

IHost
创建一个扩展方法,并在运行应用程序之前在我的
Program.cs
Main
函数中调用它,例如:

public static async Task<IHost> SeedAsync(this IHost host)
{
  using var scope = host.Services.CreateScope();
  IServiceProvider serviceProvider = scope.ServiceProvider;

  // ... use services like UserManager and RoleManager to seed user accounts ...
}

无论如何,似乎虽然

UserManager
已按预期注册,但
RoleManager
没有可用的服务:当尝试获取它时,我收到异常“'No service for type 'Microsoft.AspNetCore.Identity.RoleManager`1 [Microsoft.AspNetCore.Identity.IdentityRole]'已注册。'"。

这是一个示例重现过程:

(1) 创建一个新的 ASP.NET Core 8 Web API 应用程序。未选择身份。

(2)添加包:

  • Microsoft.AspNetCore.Identity.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.InMemory

(3)添加

AppUser.cs
AppDbContext.cs
,并将
Program.cs
更改如下:

// AppUser.cs
public class AppUser : IdentityUser
{
}

// AppDbContext.cs
public class AppDbContext : IdentityDbContext<AppUser>
{
    public AppDbContext(DbContextOptions<AppDbContext> options) :
        base(options)
    { }
}

// Program.cs
public static class Program
{
    private static void ConfigureAuthServices(IServiceCollection services,
        IConfiguration configuration)
    {
        services.AddDbContext<AppDbContext>(
            options => options.UseInMemoryDatabase("Test"));

        services.AddAuthorization();

        services.AddIdentityApiEndpoints<AppUser>()
            .AddEntityFrameworkStores<AppDbContext>();
    }

    private static void ConfigureServices(IServiceCollection services,
        IConfiguration configuration)
    {
        // auth
        ConfigureAuthServices(services, configuration);

        // API controllers
        services.AddControllers();

        // Swagger/OpenAPI (https://aka.ms/aspnetcore/swashbuckle)
        services.AddEndpointsApiExplorer();
        services.AddSwaggerGen();

        // database initializer
        services.AddScoped(sp =>
        {
            return new AppDatabaseInitializer(
                sp.GetRequiredService<UserManager<AppUser>>(),
                sp.GetRequiredService<RoleManager<IdentityRole>>(),
                configuration,
                sp.GetRequiredService<ILogger<AppDatabaseInitializer>>());
        });
    }

    public static async Task Main(string[] args)
    {
        WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
        ConfigureServices(builder.Services, builder.Configuration);

        WebApplication app = builder.Build();
        app.MapGroup("/account").MapIdentityApi<AppUser>();
        app.UseSwagger();
        app.UseSwaggerUI();

        app.UseAuthorization();
        app.MapControllers();

        // testing DI for services
        using (var scope = app.Services.CreateScope())
        {
            // this works
            var um = scope.ServiceProvider.GetRequiredService<UserManager<AppUser>>();
            // ==> THIS THROWS
            var rm = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
        }

        // here I would call await app.SeedAsync(); using my extension method
        // for IHost, using an AppDatabaseInitializer service requiring UserManager
        // and RoleManager via DI. Yet, it would fail just like the above code.

        app.Run();
    }
}

如果你现在运行,你会看到它在尝试获取

RoleManager
时抛出异常(虽然它成功获取
UserManager
)。我应该如何配置这个 V8
Identity
系统,以便为 DI 正确配置
RoleManager

c# asp.net-core asp.net-identity
1个回答
0
投票

.AddRoles<IdentityRole>()
之前添加
.AddEntityFrameworkStores<AppDbContext>
,如下所示:

services.AddIdentityApiEndpoints<AppUser>()
   .AddRoles<IdentityRole>()
   .AddEntityFrameworkStores<AppDbContext>();

现在您将能够在构造函数中成功注入

RoleManager<IdentityRole> roleManager

© www.soinside.com 2019 - 2024. All rights reserved.