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

How do I seed user roles in Identity ASP.NET Core 2.1 (Identity Scaffolded)

如何在搭建身份时设置 "admin" 用户角色?

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

所以 where/how 我要在 IdentityHostingStartup 中注入 RoleManagerUserManager 吗? (我想这就是我需要的,如果有更好的方法请告诉我)

  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;
                    });
            });
        }
  }

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

我通常的建议是在创建 WebHost 之后在 Program.cs 中执行初始播种。按照默认模板,我将 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();
}

所以这将首先创建网络主机,然后它将创建一个依赖项注入范围,它将从中解析一个 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();
}

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

另一种方法是在模型构建器上使用 .HasData() 方法调用来使用 Entity Framework Core data seeding functionality。然而,这需要你的角色对象上的固定 ID,你还必须在数据库级别创建对象,而不是依赖更高级别的 RoleManager.

有点旧的线程,但这可能会帮助任何寻求它的人。您可以在 IdentityDbContext.cs 文件内的 OnModelCreating() 方法中播种用户和角色,如下所示。请注意,应预定义密钥以避免每次执行此方法时都会播种新用户和新角色:

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //Seeding a  'Administrator' role to AspNetRoles table
        modelBuilder.Entity<IdentityRole>().HasData(new IdentityRole {Id = "2c5e174e-3b0e-446f-86af-483d56fd7210", Name = "Administrator", NormalizedName = "ADMINISTRATOR".ToUpper() });


        //a hasher to hash the password before seeding the user to the db
        var hasher = new PasswordHasher<IdentityUser>();


        //Seeding the User to AspNetUsers table
        modelBuilder.Entity<IdentityUser>().HasData(
            new IdentityUser
            {
                Id = "8e445865-a24d-4543-a6c6-9443d048cdb9", // primary key
                UserName = "myuser",
                NormalizedUserName = "MYUSER",
                PasswordHash = hasher.HashPassword(null, "Pa$$w0rd")
            }
        );


        //Seeding the relation between our user and role to AspNetUserRoles table
        modelBuilder.Entity<IdentityUserRole<string>>().HasData(
            new IdentityUserRole<string>
            {
                RoleId = "2c5e174e-3b0e-446f-86af-483d56fd7210", 
                UserId = "8e445865-a24d-4543-a6c6-9443d048cdb9"
            }
        );
        

    }