나는 새로운 MVC 5를 가지고 놀았고 코드 우선 마이그레이션을 사용하여 몇 가지 모델, 컨트롤러 및 뷰 설정을 가지고 있습니다.
내 질문은 사용자와 역할을 어떻게 시드합니까? 현재 Configuration.cs의 Seed 메서드에서 일부 참조 데이터를 시드합니다. 그러나 무언가가 AccountController에 처음 도달 할 때까지 사용자 및 역할 테이블이 생성되지 않는 것으로 보입니다.
현재 두 개의 연결 문자열이 있으므로 인증 데이터를 다른 데이터베이스로 분리 할 수 있습니다.
사용자, 역할 등의 테이블을 다른 사람과 함께 채우려면 어떻게해야합니까? 그리고 계정 컨트롤러가 맞을 때가 아니라?
답변
다음은 일반적인 Seed 접근 방식의 예입니다.
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");
}
}
패키지 관리자 “update-database”를 사용했습니다. DB와 모든 테이블이 생성되고 데이터로 시드되었습니다.
답변
약간의 추가 사항이지만 “UserId를 찾을 수 없음”을 가진 모든 사람에게 적용됩니다. 시드를 시도 할 때 메시지 : (Tom Regan은 댓글에이 질문이 있었는데 저는 잠시 동안이 질문에 매달 렸습니다.)
이것은 manager.Create (사용자, “ChangeItAsap!”)가 성공하지 못했음을 의미합니다. 이것은 다른 이유가있을 수 있지만 내 암호가 유효성 검사에 성공하지 못했기 때문입니다.
데이터베이스를 시드 할 때 호출되지 않는 사용자 지정 passwordvalidator가 있었기 때문에 내가 사용했던 유효성 검사 규칙 (기본값 6 대신 minlength 4)이 적용되지 않았습니다. 암호 (및 해당 문제에 대한 다른 모든 필드)가 유효성 검사를 통과하는지 확인하십시오.
답변
이것은 Valin 답변에 대한 내 방법 기반이며 db에 역할을 추가하고 사용자에 대한 암호를 추가했습니다. 이 코드는 Seed()
Migrations> Configurations.cs의 메서드에 있습니다.
// 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]);
}
답변
여기에 매우 쉽고 깨끗하고 부드러운 솔루션이 있습니다.
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);
}
답변
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);
}
}
답변
MVC5에서 인증이 작동하는 방식을 변경하고 Global.asax.cs를 다음과 같이 변경 한 것 같습니다.
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();
}
}
}
답변
마이그레이션 구성에이 코드를 작성하십시오.
참고 : 구성 클래스에서 ApplicationDbContext를 사용하십시오.
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" }
);
}
}