如何在Identity ASP.NET Core 2.1(Identity Scaffolded)中为用户角色添加种子

时间:2018-10-08 18:52:41

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

当身份被屏蔽时,如何播种“管理员”用户角色?

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

那我在哪里/如何在RoleManager中注入UserManagerIdentityHostingStartup? (我认为这是我所需要的,如果有更好的方法,请告诉我)

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

2 个答案:

答案 0 :(得分:3)

您不能在Web主机 builder 上执行数据播种,因为那时尚未构建服务提供商。取而代之的是,您必须先创建虚拟主机,然后才能解析以前注册的任何服务。

我通常的建议是在创建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();
}

因此,这将首先创建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();
}

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

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

答案 1 :(得分:0)

有点旧的线程,但这可能会帮助任何寻求它的人。您可以在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"
            }
        );
        

    }