Search code examples
c#asp.net-identityasp.net-core-2.0seeding

How to seed a user identity properly in asp core2?


I have this seeding class which keeps failing to insert a record in the users table,

I believe that using CreateAsync is not proper since the method is not async the user manager does not seed the record. so I tried to seed manually using hashed password but I can't login. I am posting both methods

Why the user info is not inserted on the database initialization? 1. Using UserManager CreateAsync

       public void SeedData()
        {
            using (var serviceScope = scopeFactory.CreateScope())
            {
                using (var context = serviceScope.ServiceProvider.GetService<ArtCoreDbContext>())
                {
         if (!context.ApplicationUser.Any())
                  {
               var user = new ApplicationUser
                        {
                            CityId = context.Cities.Where(g => g.Name == "Abu Nusair").SingleOrDefault().Id,
                            CountryId = context.Countries.Where(g => g.Name == "Jordan").SingleOrDefault().Id,
                             Email = "[email protected]",
                            FirstName = "Zaid",
                            GenderId = context.Genders.Where(g => g.Name == "Female").SingleOrDefault().Id,
                            IsActive = true,
                            LastName = "Abu Maizar",
                            MaritalStatusId = context.MaritalStatus.Where(g => g.Name == "Single").SingleOrDefault().Id,
                            NationalityId = context.Nationalities.Where(g => g.Name == "Jordanian").SingleOrDefault().Id,
                            OccupationId = context.Occupations.Where(g => g.Name == "MD").SingleOrDefault().Id,
                             PersonalPhotoUrl = null,
                             PhoneNumber = "4243244990",
                             PhoneNumberConfirmed = false,
                             PostalCode = 91335,
                             SocialSecurityNo = "AABBCC",
                            StateId = context.States.Where(g => g.Name == "Amman").SingleOrDefault().Id,
                            StatusId = context.Statuses.Where(g => g.Name == "Active").SingleOrDefault().Id,
                             UserName = "Zaid",

                        };
                         userManager.CreateAsync(user, "String@string85");
                         context.SaveChanges();
                    }

                }
            }
        }

2. Manual Seed,

         public void SeedData()
            {
                using (var serviceScope = scopeFactory.CreateScope())
                {
                    using (var context = serviceScope.ServiceProvider.GetService<ArtCoreDbContext>())
                    {
                        if (!context.ApplicationUser.Any())
                        {

                            context.ApplicationUser.AddRange(
                             new ApplicationUser
                             {
                                 Id = Guid.NewGuid().ToString("N"),
                                 AccessFailedCount = 0,
                                 AdminLevel = "LA",
                                 ApartmentNo = 0,
                                 CityId = context.Cities.Where(g => g.Name == "Abu Nusair").SingleOrDefault().Id,
                                 ConcurrencyStamp = Guid.NewGuid().ToString("N"),
                                 ContactAddress = "USA",
                                 ContactCountry = "USA",
                                 CountryId = context.Countries.Where(g => g.Name == "Jordan").SingleOrDefault().Id,
                                 DateCreated = DateTime.UtcNow,
                                 Email = "[email protected]",
                                 EmailConfirmed = false,
                                 FirstName = "Zaid",
                                 GenderId = context.Genders.Where(g => g.Name == "Female").SingleOrDefault().Id,
                                 IsActive = true,
                                 LastLoggedIn = DateTime.UtcNow,
                                 LastName = "Abu Maizar",
                                 Locality = "LA",
                                 LockoutEnabled = true,
                                 LockoutEnd = null,
                                 MaritalStatusId = context.MaritalStatus.Where(g => g.Name == "Single").SingleOrDefault().Id,
                                 NationalityId = context.Nationalities.Where(g => g.Name == "Jordanian").SingleOrDefault().Id,
                                 NormalizedEmail = "[email protected]",
                                 NormalizedUserName = "ZAID",
                                 OccupationId = context.Occupations.Where(g => g.Name == "MD").SingleOrDefault().Id,
                                 PasswordHash = HashPassword("Zaid@core85"),
                                 PersonalPhotoUrl = null,
                                 PhoneNumber = "4243244990",
                                 PhoneNumberConfirmed = false,
                                 PostalCode = 91335,
                                 SecurityStamp = Guid.NewGuid().ToString("N"),
                                 SocialSecurityNo = "AABBCC",
                                 StateId = context.States.Where(g => g.Name == "Amman").SingleOrDefault().Id,
                                  StatusId = context.Statuses.Where(g => g.Name == "Active").SingleOrDefault().Id,
                                 StreetDirection = "LA",
                                 StreetNo = "123231",
                                 TwoFactorEnabled = false,
                                 UserName = "Zaid",
                                 VerificationPhotoUrl = null

                             }
                        );
                            context.SaveChanges();
                        }
                    }
                }
            }

Password Hashing Method,

public static string HashPassword(string password)
        {
            byte[] salt;
            byte[] buffer2;
            if (password == null)
            {
                throw new ArgumentNullException("password");
            }
            using (Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(password, 0x10, 0x3e8))
            {
                salt = bytes.Salt;
                buffer2 = bytes.GetBytes(0x20);
            }
            byte[] dst = new byte[0x31];
            Buffer.BlockCopy(salt, 0, dst, 1, 0x10);
            Buffer.BlockCopy(buffer2, 0, dst, 0x11, 0x20);
            return Convert.ToBase64String(dst);
        }

Solution

  • There is a similar topic here: Creating Asp.net Identity user in Seed method of Db Initializer

    So you need to use non-async extension methods. Add Microsoft.AspNet.Identity assembly and using Microsoft.AspNet.Identity.

    There is an example: https://stackoverflow.com/a/27499759/3710672

    About manual seeding. I think you can't login cause the HashPassword function that you're using has different algorithm from what UserManager uses when checks password.

    To make it work try to use userManager.PasswordHasher.HashPassword(..) method instead of your function.

    In your ApplicationUser:

    ...
    PasswordHash = userManager.PasswordHasher.HashPassword("Zaid@core85"),
    ...