wake-up-neo.com

Wie erstelle ich einen Admin-Benutzer in EF Core 2.1.0?

Ich habe eine ASP.NET Core 2.1.0-Anwendung mit EF Core 2.1.0.

Wie gehe ich vor, um die Datenbank mit dem Administratorbenutzer zu erstellen und ihm/ihr eine Administratorrolle zuzuweisen? Ich kann dazu keine Dokumentation finden.

26
J86

Da Benutzer nicht auf normale Weise in Identity festgelegt werden können, wie andere Tabellen mit .HasData() von .NET Core 2.1.

Seed-Rollen in .NET Core 2.1 mit dem unten in ApplicationDbContext angegebenen Code. Klasse:

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);

        modelBuilder.Entity<IdentityRole>().HasData(new IdentityRole { Name = "Admin", NormalizedName = "Admin".ToUpper() });
    }

Benutzer mit Rollen festlegen indem Sie die folgenden Schritte ausführen.

Schritt 1: Neue Klassenerstellung

public static class ApplicationDbInitializer
{
    public static void SeedUsers(UserManager<IdentityUser> userManager)
    {
        if (userManager.FindByEmailAsync("[email protected]").Result==null)
        {
            IdentityUser user = new IdentityUser
            {
                UserName = "[email protected]",
                Email = "[email protected]"
            };

            IdentityResult result = userManager.CreateAsync(user, "PasswordHere").Result;

            if (result.Succeeded)
            {
                userManager.AddToRoleAsync(user, "Admin").Wait();
            }
        }       
    }   
}

Schritt 2: Ändern Sie nun die ConfigureServices Methode in Startup.cs Klasse.

Vor der Änderung:

services.AddDefaultIdentity<IdentityUser>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

Nach der Modifikation:

services.AddDefaultIdentity<IdentityUser>().AddRoles<IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

Schritt 3: Ändern Sie die Parameter von Configure Methode in Startup.cs Klasse.

Vor der Änderung:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        //..........
    }

Nach der Modifikation :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, UserManager<IdentityUser> userManager)
    {
        //..........
    }

Schritt 4: Aufruf der Methode unserer Klasse Seed (ApplicationDbInitializer):

ApplicationDbInitializer.SeedUsers(userManager);
35
Zubair Rana

Tatsächlich kann eine User -Entität in OnModelCreating gesetzt werden, wobei eines zu beachten ist: Die IDs sollten vordefiniert sein. Wenn der Typ string für TKey Identitätseinheiten verwendet wird, gibt es überhaupt kein Problem.

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);
    // any guid
    const string ADMIN_ID = "a18be9c0-aa65-4af8-bd17-00bd9344e575";
    // any guid, but nothing is against to use the same one
    const string ROLE_ID = ADMIN_ID;
    builder.Entity<IdentityRole>().HasData(new IdentityRole
    {
        Id = ROLE_ID,
        Name = "admin",
        NormalizedName = "admin"
    });

    var hasher = new PasswordHasher<UserEntity>();
    builder.Entity<UserEntity>().HasData(new UserEntity
    {
        Id = ADMIN_ID,
        UserName = "admin",
        NormalizedUserName = "admin",
        Email = "[email protected]",
        NormalizedEmail = "[email protected]",
        EmailConfirmed = true,
        PasswordHash = hasher.HashPassword(null, "SOME_ADMIN_PLAIN_PASSWORD"),
        SecurityStamp = string.Empty
    });

    builder.Entity<IdentityUserRole<string>>().HasData(new IdentityUserRole<string>
    {
        RoleId = ROLE_ID,
        UserId = ADMIN_ID
    });
}
23
tenbits

Hier ist, wie ich es am Ende gemacht habe. Ich habe ein DbInitializer.cs Klasse, um das Seeding aller meiner Daten (einschließlich des Administrators) durchzuführen.

screenshot

Hier ist der Code für die Methoden zum Seeding der Benutzerkonten:

private static async Task CreateRole(RoleManager<IdentityRole> roleManager, 
ILogger<DbInitializer> logger, string role)
{
  logger.LogInformation($"Create the role `{role}` for application");
  IdentityResult result = await roleManager.CreateAsync(new IdentityRole(role));
  if (result.Succeeded)
  {
    logger.LogDebug($"Created the role `{role}` successfully");
  }
  else
  {
    ApplicationException exception = new ApplicationException($"Default role `{role}` cannot be created");
    logger.LogError(exception, GetIdentiryErrorsInCommaSeperatedList(result));
    throw exception;
  }
}

private static async Task<ApplicationUser> CreateDefaultUser(UserManager<ApplicationUser> userManager, ILogger<DbInitializer> logger, string displayName, string email)
{
  logger.LogInformation($"Create default user with email `{email}` for application");

  ApplicationUser user = new ApplicationUser
  {
    DisplayUsername = displayName,
    Email = email,
    UserName = email
  };

  IdentityResult identityResult = await userManager.CreateAsync(user);

  if (identityResult.Succeeded)
  {
    logger.LogDebug($"Created default user `{email}` successfully");
  }
  else
  {
    ApplicationException exception = new ApplicationException($"Default user `{email}` cannot be created");
    logger.LogError(exception, GetIdentiryErrorsInCommaSeperatedList(identityResult));
    throw exception;
  }

  ApplicationUser createdUser = await userManager.FindByEmailAsync(email);
  return createdUser;
}

private static async Task SetPasswordForUser(UserManager<ApplicationUser> userManager, ILogger<DbInitializer> logger, string email, ApplicationUser user, string password)
{
  logger.LogInformation($"Set password for default user `{email}`");
  IdentityResult identityResult = await userManager.AddPasswordAsync(user, password);
  if (identityResult.Succeeded)
  {
    logger.LogTrace($"Set password `{password}` for default user `{email}` successfully");
  }
  else
  {
    ApplicationException exception = new ApplicationException($"Password for the user `{email}` cannot be set");
    logger.LogError(exception, GetIdentiryErrorsInCommaSeperatedList(identityResult));
    throw exception;
  }
}

Mein Program.cs sieht aus wie das:

public class Program
{
  public static async Task Main(string[] args)
  {
    var Host = BuildWebHost(args);

    using (var scope = Host.Services.CreateScope())
    {
      var services = scope.ServiceProvider;
      Console.WriteLine(services.GetService<IConfiguration>().GetConnectionString("DefaultConnection"));
      try
      {
        var context = services.GetRequiredService<PdContext>();
        var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
        var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>();

        var dbInitializerLogger = services.GetRequiredService<ILogger<DbInitializer>>();
        await DbInitializer.Initialize(context, userManager, roleManager, dbInitializerLogger);
      }
      catch (Exception ex)
      {
        var logger = services.GetRequiredService<ILogger<Program>>();
        logger.LogError(ex, "An error occurred while migrating the database.");
      }
    }

    Host.Run();
  }

  public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
    .UseStartup<Startup>()
    .Build();
}
1
J86