2016-10-08 2 views
16

In einer ASP.NET Core-Anwendung möchte ich bestimmte Rollen als Grundlage für die Verwaltung verschiedener Benutzerberechtigungen erstellen. Leider enthält die Dokumentation detaillierte Informationen zur Verwendung von benutzerdefinierten Rollen, z. in Controllern/Aktionen, aber nicht wie man sie erstellt. Ich fand heraus, dass ich dafür RoleManager<IdentityRole> verwenden kann, wo die Instanz automatisch in einen Controller-Konstruktor injiziert wird, wenn ihre definierte und ASP.NET Core-Identität in der Anwendung registriert ist.ASP.NET Core Identity Hinzufügen von benutzerdefinierten Benutzerrollen beim Start der Anwendung

Diese lassen Sie mich eine benutzerdefinierte Rolle wie folgt hinzu:

var testRole = new IdentityRole("TestRole"); 
if(!roleManager.RoleExistsAsync(testRole.Name).Result) { 
    roleManager.CreateAsync(testRole); 
} 

Es funktioniert und die Rolle in der Datenbank erstellen. Diese Überprüfung erzeugt jedoch immer einen Overhead für die Datenbank und ruft den spezifischen Controller/Vorgang auf. Also ich möchte einmal überprüfen, nachdem meine Anwendung gestartet wurde, wenn die benutzerdefinierte Rolle vorhanden ist und sie hinzufügen. Die Methode ConfigureServices in Startup.cs scheint dafür gut zu sein.

Aber: Wie kann ich eine Instanz der RoleManager<IdentityRole> Klasse dafür erstellen? Ich würde gerne einen Best-Practice-Ansatz hier verwenden und nicht herumrennen, indem ich abhängige Instanzen selbst erstellen würde, was eine Menge Arbeit verursacht, da es nicht gut dokumentiert ist und sicher nicht den Best Practices folgen wird, da ASP.NET Core verwendet Abhängigkeitsinjektion für solche Dinge (was meiner Meinung nach auch vernünftig ist).

Mit anderen Worten: Ich brauche abhängige Injektion außerhalb eines Controllers. Hier

+0

Sie vielleicht in meinem Projekt interessiert sein, die Verwaltung für Identity-Benutzer bereitstellt, Rollen und Ansprüche https://github.com/joeaudette/cloudscribe –

Antwort

24

ist ein Beispiel für Ihre Bedürfnisse, die migriert und Samen die Datenbank beim Start:

Erstellen Sie eine statische Klasse:

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

Und in Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    ... 

    RolesData.SeedRoles(app.ApplicationServices).Wait(); 
} 
+1

Wenn Sie Migrationen verwenden, ist die Bedingung 'if (g \ u00e4t db.Database.EnsureCreatedAsync())' '' false '', so dass keine Rollen erstellt werden. – Artholl

+0

@Artholl Guter Fang. Ich ersetze mit 'if (dbContext.Database.GetPendingMigrations(). Any())' und 'erwarten dbContext.Database.MigrateAsync();' – tmg

+0

Versuchen Sie die IF nur, wenn Migrationen ausgeführt werden ... Etwas wie 'if (dbContext .Database.GetPendingMigrations(). Any()) erwarten dbContext.Database.MigrateAsync(); ' – Yuki

5

Ich würde es vorziehen um die Daten nur zu säen, wenn noch keine Rollen in der Datenbank eingefügt sind. Mit anderen Worten nur die Rollen speichern, wenn die Anwendung zum ersten Mal ausgeführt wird:

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

     } 
    } 
} 

Und auf Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    ... 

    RolesData.SeedRoles(app.ApplicationServices).Wait(); 
} 
Verwandte Themen