c# - custom - ASP.NET Core Identity Agregue roles de usuario personalizados en el inicio de la aplicaciĆ³n
identity server 4 asp net core 2 (2)
En una aplicación Core de ASP.NET, quiero crear ciertos roles como base para administrar diferentes permisos de usuario. Lamentablemente, la documentación informa cómo usar roles personalizados, por ejemplo, en controladores / acciones, pero no cómo crearlos. Descubrí que puedo usar RoleManager<IdentityRole>
para esto, donde la instancia se inyecta automáticamente en un controlador-constructor, cuando su identidad Core y ASP.NET definida está registrada en la aplicación.
Esto me permite agregar un rol personalizado como este:
var testRole = new IdentityRole("TestRole");
if(!roleManager.RoleExistsAsync(testRole.Name).Result) {
roleManager.CreateAsync(testRole);
}
Funciona y crea el rol en la base de datos. Pero esta comprobación siempre creará una sobrecarga en la base de datos, llamando al controlador / acción específico. Así que quiero verificar una vez que mi aplicación haya comenzado, si existe el rol personalizado y agregarlos. El método ConfigureServices
en Startup.cs parece bueno para esto.
Pero: ¿Cómo puedo crear una instancia de la RoleManager<IdentityRole>
para hacer esto? Me gustaría usar un enfoque de mejores prácticas aquí y no perder el tiempo creando instancias dependientes por mi cuenta, lo que parece causar mucho trabajo ya que no está bien documentado y seguramente no seguirá las mejores prácticas, ya que ASP.NET Core está usando inyección de dependencia para cosas como esta (que también es razonable en mi opinión).
En otras palabras: necesito usar inyección dependiente fuera de un controlador.
Este es un ejemplo de sus necesidades que migra y siembra la base de datos en el inicio:
Crear una clase estática:
public static class RolesData
{
private static readonly string[] Roles = new string[] {"Administrator", "Editor", "Subscriber"};
public static async Task SeedRoles(IServiceProvider serviceProvider)
{
using (var serviceScope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var dbContext = serviceScope.ServiceProvider.GetService<ApplicationDbContext>();
if (dbContext.Database.GetPendingMigrations().Any())
{
await dbContext.Database.MigrateAsync();
var roleManager = serviceScope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
foreach (var role in Roles)
{
if (!await roleManager.RoleExistsAsync(role))
{
await roleManager.CreateAsync(new IdentityRole(role));
}
}
}
}
}
}
Y en Startup.cs
:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
RolesData.SeedRoles(app.ApplicationServices).Wait();
}
Preferiría sembrar los datos solo si no hay roles ya insertados en la base de datos. En otras palabras, almacene los roles solo cuando la aplicación se ejecute por primera vez:
public static class RolesData
{
private static readonly string[] Roles = new string[] { "Administrator", "Editor", "Subscriber" };
public static async Task SeedRoles(IServiceProvider serviceProvider)
{
using (var serviceScope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var dbContext = serviceScope.ServiceProvider.GetService<AppDbContext>();
if (!dbContext.UserRoles.Any())
{
var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
foreach (var role in Roles)
{
if (!await roleManager.RoleExistsAsync(role))
{
await roleManager.CreateAsync(new IdentityRole(role));
}
}
}
}
}
}
Y en Startup.cs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
RolesData.SeedRoles(app.ApplicationServices).Wait();
}