MVC 5 Başlangıç ​​Kullanıcıları ve Rolleri


95

Yeni MVC 5 ile oynuyordum, birkaç modelim, denetleyicim ve ilk kod geçişlerini kullanan görünüm kurulumum var.

Sorum şu: kullanıcıları ve rolleri nasıl başlatırım? Şu anda Configuration.cs içindeki Tohum yöntemime bazı referans verileri ekliyorum. Ama bana öyle geliyor ki, bir şey AccountController'a ilk ulaşana kadar kullanıcı ve rol tabloları oluşturulmamış.

Şu anda iki bağlantı dizim var, böylece verilerimi kimlik doğrulamamdan farklı veritabanlarına ayırabilirim.

Başkalarımla birlikte kullanıcı, roller vb. Tabloların doldurulmasını nasıl sağlayabilirim? Ve hesap denetleyicisine vurulduğunda değil mi?


Yanıtlar:


183

İşte olağan Tohum yaklaşımı örneği:

protected override void Seed(SecurityModule.DataContexts.IdentityDb context)
{
    if (!context.Roles.Any(r => r.Name == "AppAdmin"))
    {
        var store = new RoleStore<IdentityRole>(context);
        var manager = new RoleManager<IdentityRole>(store);
        var role = new IdentityRole { Name = "AppAdmin" };

        manager.Create(role);
    }

    if (!context.Users.Any(u => u.UserName == "founder"))
    {
        var store = new UserStore<ApplicationUser>(context);
        var manager = new UserManager<ApplicationUser>(store);
        var user = new ApplicationUser {UserName = "founder"};

        manager.Create(user, "ChangeItAsap!");
        manager.AddToRole(user.Id, "AppAdmin");
    }
}

Paket yöneticisi "güncelleme-veritabanı" kullandım. DB ve tüm tablolar oluşturuldu ve verilerle tohumlandı.


3
Configuration sınıfının Seed yöntemine. Yapılandırma, geçişleri etkinleştirmek için varsayılan sınıf adıdır, ancak bunu değiştirebilirsiniz.
Valin

3
Paket yöneticisi konsolunu 'enable-migrations' kullanmalısınız. Sizin için seed yöntemi ile konfigürasyon sınıfı oluşturacaktır.
Valin

4
@Zapnologica Migrations kullanımı çok kolay. Ayrıca tablolarınızı yeniden oluşturmadan tablolarınızı düzenlemenize de olanak tanır. NuGet Paket Yöneticisi Konsolu'nu kullanmaya alışmanız gereken yalnızca üç komut vardır. Enable-Migrations, Add-Migration ve update-database. Kolay peazy.
yardpenalty.com

10
Kelimenin tam anlamıyla bu kodu kopyalayıp yeni bir mvc 5 web uygulamasındaki Tohum yöntemime yapıştırdım ve ardından paket yöneticisi konsolunda "güncelleme-veritabanı" çalıştırdım. Rolü ekler (AspNetRoles tablosunda görebiliyorum), ancak satır yöneticisine gelince.AddToRole (user.Id, "AppAdmin") "UserId not found" hata mesajını alıyorum. Neyi kaçırdığım konusunda herhangi bir fikriniz varsa, bu bilgiyi çok takdir ediyorum
Tom Regan

2
Kaçırılan context.Users.Add(user);arasında manager.Create(user, "ChangeItAsap!");ve manager.AddToRole(user.Id, "AppAdmin");. Yani yeni doğan kullanıcının User.Id.
ApceH Hypocrite

15

Küçük bir eklentidir, ancak "UserId bulunamadı" olan herkes için. tohumlamaya çalışırken mesaj: (Tom Regan'ın bu sorusu yorumlarda vardı ve ben bir süre kendime takılı kaldım)

Bu, manager.Create (kullanıcı, "ChangeItAsap!") İşleminin başarılı olmadığı anlamına gelir. Bunun farklı bir nedeni olabilir, ancak benim için bunun nedeni parolamın doğrulamada başarılı olmamasıydı.

Veritabanını tohumlarken çağrılmayan özel bir parola doğrulayıcım vardı, bu nedenle kullandığım doğrulama kuralları (varsayılan 6 yerine minimum uzunluk 4) uygulanmadı. Parolanızın (ve bu konudaki diğer tüm alanların) doğrulamadan geçtiğinden emin olun.


7
"UserId not found" sorunu yaşadığım için bu bana yardımcı oldu. Aşağıdaki kodla onu bulmayı başardım: IdentityResult result = manager.Create(user, "ChangeItAsap!"); if (result.Succeeded == false) { throw new Exception(result.Errors.First()); }
Steve Wilford

Bu yorum mükemmel, bana 'Kullanıcı adı Demo Kullanıcı geçersiz, sadece harf veya rakam içerebilir' verdi. eksik bir userId ile belirsiz bir şekilde başarısız olmak yerine
dougajmcdonald

Şifre doğrulama kuralımın da çalışmadığını buldum, herhangi bir fikriniz var mı?
user1686407

15

Bu, Valin cevabındaki yöntemimin temelidir, db'de roller ekledim ve kullanıcı için şifre ekledim. Bu kod, Seed()Migrations> Configurations.cs içindeki yönteme yerleştirilir .

// role (Const.getRoles() return string[] whit all roles)

    var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
    for (int i = 0; i < Const.getRoles().Length; i++)
    {
        if (RoleManager.RoleExists(Const.getRoles()[i]) == false)
        {
            RoleManager.Create(new IdentityRole(Const.getRoles()[i]));
        }
    }

// user

    var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
    var PasswordHash = new PasswordHasher();
    if (!context.Users.Any(u => u.UserName == "admin@admin.net"))
    {
        var user = new ApplicationUser
        {
             UserName = "admin@admin.net",
             Email = "admin@admin.net",
             PasswordHash = PasswordHash.HashPassword("123456")
         };

         UserManager.Create(user);
         UserManager.AddToRole(user.Id, Const.getRoles()[0]);
    }

6

Burada çok kolay, temiz ve pürüzsüz bir çözümüm var.

 protected override void Seed(UserContext context)
    { 
        //Step 1 Create the user.
        var passwordHasher = new PasswordHasher();
        var user = new IdentityUser("Administrator");
        user.PasswordHash = passwordHasher.HashPassword("Admin12345");
        user.SecurityStamp = Guid.NewGuid().ToString();

        //Step 2 Create and add the new Role.
        var roleToChoose = new IdentityRole("Admin");
        context.Roles.Add(roleToChoose);

        //Step 3 Create a role for a user
        var role = new IdentityUserRole();
        role.RoleId = roleToChoose.Id;
        role.UserId = user.Id;

         //Step 4 Add the role row and add the user to DB)
        user.Roles.Add(role);
        context.Users.Add(user);
    }

1
Harika bir şey, ama önemli bir şeyi kaçırdın. User.SecurityStamp = Guid.NewGuid (). ToString () eklemelisiniz, yoksa oturum açarken bir hata alırsınız.
eddy white

Teşekkür. Bu özelliği kullanmadım ama cevabıma ekledim.
Mr Tangjai

4
protected override void Seed(ApplicationDbContext context)
{
  SeedAsync(context).GetAwaiter().GetResult();
}

private async Task SeedAsync(ApplicationDbContext context)
{
  var userManager = new ApplicationUserManager(new UserStore<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(context));
  var roleManager = new ApplicationRoleManager(new RoleStore<ApplicationRole, int, ApplicationUserRole>(context));

  if (!roleManager.Roles.Any())
  {
    await roleManager.CreateAsync(new ApplicationRole { Name = ApplicationRole.AdminRoleName });
    await roleManager.CreateAsync(new ApplicationRole { Name = ApplicationRole.AffiliateRoleName });
  }

  if (!userManager.Users.Any(u => u.UserName == "shimmy"))
  {
    var user = new ApplicationUser
    {
      UserName = "shimmy",
      Email = "shimmy@gmail.com",
      EmailConfirmed = true,
      PhoneNumber = "0123456789",
      PhoneNumberConfirmed = true
    };

    await userManager.CreateAsync(user, "****");
    await userManager.AddToRoleAsync(user.Id, ApplicationRole.AdminRoleName);
  }
}

1
ApplicationUser'ımı int typed ID özelliğine sahip olacak şekilde özelleştirdim. Yaklaşımınız, özel Kullanıcı ve Rol Depolarımla çalışabileceğim tek yaklaşımdır, teşekkürler!
Mike Devenney

1
Bu bit kavramsal bir noktada tamamen yanlış: Task.Run(async () => { await SeedAsync(context); }).Wait();. SeedAsync(context).GetAwait().GetResult();Hangisinin daha iyi olduğunu yazmayı tercih etmelisiniz .
Tanveer Badar

2

MVC5'te kimlik doğrulamasının çalışma şeklini değiştirmiş gibi görünüyorlar, Global.asax.cs'imi aşağıdaki hile yaptı!

using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

using System.Threading.Tasks;
using MvcAuth.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using System.Threading;
using Microsoft.AspNet.Identity.EntityFramework;

namespace MvcAuth
{
    public class MvcApplication : System.Web.HttpApplication
    {
        async Task<bool> AddRoleAndUser()
        {
            AuthenticationIdentityManager IdentityManager = new AuthenticationIdentityManager(
                new IdentityStore(new ApplicationDbContext()));

            var role = new Role("Role1");
            IdentityResult result = await IdentityManager.Roles.CreateRoleAsync(role, CancellationToken.None);
            if (result.Success == false)
                return false;

            var user = new ApplicationUser() { UserName = "user1" };
            result = await IdentityManager.Users.CreateLocalUserAsync(user, "Password1");
            if (result.Success == false)
                return false;

            result = await IdentityManager.Roles.AddUserToRoleAsync(user.Id, role.Id, CancellationToken.None);
            return result.Success;
        }

        protected async void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            bool x = await AddRoleAndUser();
        }
    }
}

9
ASP.NET Identity API değiştiği için bu yanıt artık geçerli değildir.
Josh McKearin

@Josh McKearin Daha iyi bir çözümünüz var mı? lütfen paylaşın
Victor.Uduak

2

bu kodu Taşıma Yapılandırmanıza yazın.

not: Yapılandırma Sınıfında ApplicationDbContext kullanın.

    internal sealed class Configuration : DbMigrationsConfiguration<ApplicationDbContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
        AutomaticMigrationDataLossAllowed = false;
    }

    protected override void Seed(ApplicationDbContext context)
    {
        //  This method will be called after migrating to the latest version.

        //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
        //  to avoid creating duplicate seed data.
                   context.Roles.AddOrUpdate(p =>
            p.Id,
                new IdentityRole { Name = "Admins"},
                new IdentityRole { Name = "PowerUsers" },
                new IdentityRole { Name = "Users" },
                new IdentityRole { Name = "Anonymous" }
            );


    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.