简体   繁体   English

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

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

How do I seed a "admin" user role when identity is scaffolded?搭建身份时如何为“管理员”用户角色播种?

I would like to find my power-user account by email and seed the admin role.我想通过电子邮件找到我的超级用户帐户并设置管理员角色。 Most examples I find use Startup.cs , but you are supposed to use IdentityHostingStartup.cs to register identity related services.我发现的大多数示例都使用Startup.cs ,但您应该使用IdentityHostingStartup.cs来注册与身份相关的服务。

So where/how do I inject the RoleManager and UserManager in IdentityHostingStartup ?那么我在哪里/如何在IdentityHostingStartup中注入RoleManagerUserManager (I assume this is what I need, please let me know if there is a better way) (我想这是我需要的,如果有更好的方法请告诉我)

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

You cannot perform data seeding on the web host builder since at that time, the service provider has not been built yet.您无法在 Web 主机构建器上执行数据播种,因为那时服务提供商尚未构建。 Instead, you will have to actually create the web host first before you can resolve any services you have registered before.相反,您必须先实际创建虚拟主机,然后才能解析您之前注册的任何服务。

My usual recommendation is to perform the initial seeding in the Program.cs after the WebHost is created.我通常的建议是在创建WebHost后在Program.cs中执行初始播种。 Following the default template, I would adjust the Main method to look like this:按照默认模板,我将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();
}

So this will first create the web host, then it will create a dependency injection scope from which it will resolve a RoleManager instance.所以这将首先创建 web 主机,然后它将创建一个依赖注入范围,它将从中解析RoleManager实例。 Using that manager you then can create the roles you require.然后,您可以使用该管理器创建所需的角色。

You could also create a separate service for this, so you do not need to have all that logic inside the Program.cs but can just rely on some other service to perform the data seeding:您还可以为此创建一个单独的服务,因此您不需要在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();
}

The DataSeeder would then be registered with the dependency injection container.然后DataSeeder将注册到依赖注入容器中。 And then it could take the RoleManager and other services (eg options, or even the database context) as a dependency and perform the seeding in the EnsureSeedDataAsync method.然后它可以将RoleManager和其他服务(例如选项,甚至数据库上下文)作为依赖项,并在EnsureSeedDataAsync方法中执行播种。

An alternative would be to use the Entity Framework Core data seeding functionality using the .HasData() method call on the model builder.另一种方法是使用.HasData()方法调用模型生成器上的Entity Framework Core 数据播种功能 This however requires fixed IDs on your role objects and you will also have to create the objects at database level instead of relying on the higher-level RoleManager .但是,这需要角色对象上的固定 ID,并且您还必须在数据库级别创建对象,而不是依赖更高级别的RoleManager

a bit old thread but this may help anyone seeking it.有点旧的线程,但这可能会帮助任何寻求它的人。 You can seed Users and Roles in OnModelCreating() method inside IdentityDbContext.cs file as shown below.您可以在 IdentityDbContext.cs 文件中的 OnModelCreating() 方法中为用户和角色播种,如下所示。 Note that the keys should be predefined to avoid seeding new users and new roles everytime this method is executed:请注意,应预定义密钥以避免每次执行此方法时播种新用户和新角色:

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

    }

My Local version EF Core 6.0.3 required a Primary Key for uniqueness.我的本地版本 EF Core 6.0.3 需要一个主键来保证唯一性。

Updated Code:更新代码:

//Seeding the relation between our user and role to AspNetUserRoles table

modelBuilder.Entity<IdentityUserRole<Guid>>().HasKey(x => new { x.RoleId, x.UserId });

modelBuilder.Entity<IdentityUserRole<string>>().HasData(
new IdentityUserRole<string>
            {
                RoleId = "2c5e174e-3b0e-446f-86af-483d56fd7210", 
                UserId = "8e445865-a24d-4543-a6c6-9443d048cdb9"
            }
        );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 种子 ASP.NET .NET Core 3.1 中的身份用户和角色 - Seed ASP.NET Identity user and roles in .NET Core 3.1 ASP.NET核心身份种子仅创建最后一个用户 - ASP.NET core Identity seed only creates the last user 如何使用ASP.NET Identity将用户播种到数据库中? - How to seed a user into the database with ASP.NET Identity? 如何在没有角色的情况下使用ASP.NET Core Identity? - How to use ASP.NET Core Identity without roles? 如何在ASP.NET Core 2.1 Identity UI中进行自定义路由? - How to do custom routing in asp.net core 2.1 identity ui? 如何检查用户在asp.net身份中是否担任过多个角色 - How to check user is in many roles in asp.net identity 在ASP.NET Core上使用Identity登录后,如何直接获取用户详细信息? - How do I get the user details straight after login using Identity on ASP.NET Core? ASP.Net Core - 如何在登录后等待用户身份立即可用? - ASP.Net Core - How do I wait for User Identity to be available immediately after signing in? 如何在ASP.NET Identity框架中对用户进行身份验证? - How do I authenticate user in ASP.NET Identity framework? 如何将Identity Server与.NET Core 2.1配合使用? - How do I use Identity Server with .NET Core 2.1?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM