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 us
You cannot perform data seeding on the web host builder since at that time, the service provider has not been built yet. 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. Following the default template, I would adjust the Main
method to look like this:
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. 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:
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. And then it could take the RoleManager
and other services (e.g. options, or even the database context) as a dependency and perform the seeding in the EnsureSeedDataAsync
method.
An alternative would be to use the Entity Framework Core data seeding functionality using the .HasData()
method call on the model builder. 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
.
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. 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"
}
);
}