如何在 Identity ASP.NET Core 2.1 (Identity Scaffolded) 中植入用户角色

Rol*_*ter 2 c# asp.net-identity asp.net-core

当身份被构建时,如何为“管理员”用户角色设定种子?

我想通过电子邮件查找我的高级用户帐户并设置管理员角色。我发现的大多数示例都使用Startup.cs,但您应该使用它IdentityHostingStartup.cs来注册与身份相关的服务。

那么,/我如何注入RoleManagerUserManagerIdentityHostingStartup?(我假设这就是我需要的,请让我知道是否有更好的方法)

  public class IdentityHostingStartup : IHostingStartup
  {
        public void Configure(IWebHostBuilder builder)
        {
            builder.ConfigureServices((context, services) => {
                services.AddDbContext<MyWebContext>(options =>
                    options.UseSqlServer(
                        context.Configuration.GetConnectionString("MyWebContextConnection")));

                services.AddIdentity<MyWebUser, MyWebRole>()
                    .AddRoles<MyWebRole>()
                    .AddRoleManager<RoleManager<MyWebRole>>()
                    .AddDefaultUI()
                    .AddEntityFrameworkStores<MyWebContext>();

                services.Configure<IdentityOptions>(options => {
                    options.Password.RequireNonAlphanumeric = false;
                    });
            });
        }
  }
Run Code Online (Sandbox Code Playgroud)

pok*_*oke 7

您无法在 Web 主机构建器上执行数据播种,因为那时服务提供程序尚未构建。相反,您必须先实际创建 Web 主机,然后才能解析您之前注册的任何服务。

我通常的建议是在创建Program.cs之后执行初始播种WebHost。按照默认模板,我会将Main方法调整为如下所示:

public static async Task Main(string[] args)
{
    var host = CreateWebHostBuilder(args).Build();

    using (var scope = host.Services.CreateScope())
    {
        var roleManager = scope.ServiceProvider.GetService<RoleManager<MyWebRole>>();

        if (!await roleManager.RoleExistsAsync("admin"))
            await roleManager.CreateAsync(new MyWebRole { Name = "admin" });
    }

    await host.RunAsync();
}
Run Code Online (Sandbox Code Playgroud)

所以这将首先创建 web 主机,然后它将创建一个依赖注入范围,从中解析一个RoleManager实例。使用该管理器,您可以创建所需的角色。

您还可以为此创建一个单独的服务,因此您不需要在其中包含所有这些逻辑,Program.cs而只需依靠其他一些服务来执行数据播种:

public static async Task Main(string[] args)
{
    var host = CreateWebHostBuilder(args).Build();

    using (var scope = host.Services.CreateScope())
    {
        var dataSeeder = scope.ServiceProvider.GetService<DataSeeder>();
        await dataSeeder.EnsureSeedDataAsync();
    }

    await host.RunAsync();
}
Run Code Online (Sandbox Code Playgroud)

DataSeeder随后将被依赖注入容器中注册。然后它可以将RoleManager和其他服务(例如选项,甚至数据库上下文)作为依赖项并在EnsureSeedDataAsync方法中执行播种。

另一种方法是使用实体框架的核心数据直播功能使用.HasData()的模型生成方法调用。但是,这需要角色对象上的固定 ID,并且您还必须在数据库级别创建对象,而不是依赖更高级别的RoleManager.