代码之家  ›  专栏  ›  技术社区  ›  J86

如何在ef core 2.1.0中为管理员用户设置种子?

  •  21
  • J86  · 技术社区  · 7 年前

    我有一个使用ef core 2.1.0的asp.net core2.1.0应用程序。

    如何使用管理员用户对数据库进行种子设定并赋予他/她管理员角色?我找不到这方面的任何文件。

    4 回复  |  直到 7 年前
        1
  •  35
  •   Cokes    6 年前

    因为用户不能像使用 .HasData() .NET核心2.1。

    种子角色 在.NET Core 2.1中,使用下面给出的代码 ApplicationDbContext 班级:

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

    为用户添加角色 按照下面给出的步骤。

    步骤1: 新建类

    public static class ApplicationDbInitializer
    {
        public static void SeedUsers(UserManager<IdentityUser> userManager)
        {
            if (userManager.FindByEmailAsync("abc@xyz.com").Result==null)
            {
                IdentityUser user = new IdentityUser
                {
                    UserName = "abc@xyz.com",
                    Email = "abc@xyz.com"
                };
    
                IdentityResult result = userManager.CreateAsync(user, "PasswordHere").Result;
    
                if (result.Succeeded)
                {
                    userManager.AddToRoleAsync(user, "Admin").Wait();
                }
            }       
        }   
    }
    

    步骤2: 现在修改 ConfigureServices 方法在 Startup.cs 班级。

    修改前:

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

    修改后:

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

    步骤3: 修改的参数 Configure 方法在 创业公司 班级。

    修改前:

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

    修改后:

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

    步骤4 :调用种子的方法( ApplicationDbInitializer 班:

    ApplicationDbInitializer.SeedUsers(userManager);
    
        2
  •  23
  •   tenbits    6 年前

    实际上是 User 实体可以被播种 OnModelCreating ,需要考虑的一件事是: ID s应该是预定义的。如果类型 string 用于 TKey 身份实体,那么根本就没有问题。

    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 = "some-admin-email@nonce.fake",
            NormalizedEmail = "some-admin-email@nonce.fake",
            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
        });
    }
    
        3
  •  1
  •   MWD    6 年前

    这就是我最后是怎么做到的。我创造了一个 DbInitializer.cs 类来对我的所有数据(包括管理员用户)进行种子设定。

    screenshot

    以下是与用户帐户种子设定相关的方法的代码:

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

    我的 Program.cs 看起来像这样:

    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();
    }
    
        4
  •  -2
  •   Salih H.    7 年前

    如果您指的是身份用户,我们的做法是在DbContext.OnModelCreating中添加硬编码值:

    builder.Entity<Role>().HasData(new Role { Id = 2147483645, Name = UserRole.Admin.ToString(), NormalizedName = UserRole.Admin.ToString().ToUpper(), ConcurrencyStamp = "123c90a4-dfcb-4e77-91e9-d390b5b6e21b" });
    

    用户:

    builder.Entity<User>().HasData(new User
            {
                Id = 2147483646,
                AccessFailedCount = 0,
                PasswordHash = "SomePasswordHashKnownToYou",
                LockoutEnabled = true,
                FirstName = "AdminFName",
                LastName = "AdminLName",
                UserName = "admin",
                Email = "admin@gmail.com",
                EmailConfirmed = true,
                InitialPaymentCompleted = true,
                MaxUnbalancedTech = 1,
                UniqueStamp = "2a1a39ef-ccc0-459d-aa9a-eec077bfdd22",
                NormalizedEmail = "ADMIN@GMAIL.COM",
                NormalizedUserName = "ADMIN",
                TermsOfServiceAccepted = true,
                TermsOfServiceAcceptedTimestamp = new DateTime(2018, 3, 24, 7, 42, 35, 10, DateTimeKind.Utc),
                SecurityStamp = "ce907fd5-ccb4-4e96-a7ea-45712a14f5ef",
                ConcurrencyStamp = "32fe9448-0c6c-43b2-b605-802c19c333a6",
                CreatedTime = new DateTime(2018, 3, 24, 7, 42, 35, 10, DateTimeKind.Utc),
                LastModified = new DateTime(2018, 3, 24, 7, 42, 35, 10, DateTimeKind.Utc)
            });
    
    builder.Entity<UserRoles>().HasData(new UserRoles() { RoleId = 2147483645, UserId = 2147483646 });
    

    我希望有更好的/更清洁的方法来做。

    推荐文章