我创建了一个新的干净的 asp.net 5 项目(rc1-final)。使用身份验证我只有 ApplicationDbContext.cs 和以下代码:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
protected override void OnModelCreating(ModelBuilder builder)
{
// On event model creating
base.OnModelCreating(builder);
}
}
请注意 ApplicationDbContext 使用 IdentityDbContext 而不是 DbContext。
有任何IdentityConfig.cs。如果不存在,我需要将经典的 protected override void Seed 放在哪里来创建角色和用户?
我的方法是在模型命名空间中创建一个类。
public class SampleData
{
public static void Initialize(IServiceProvider serviceProvider)
{
var context = serviceProvider.GetService<ApplicationDbContext>();
string[] roles = new string[] { "Owner", "Administrator", "Manager", "Editor", "Buyer", "Business", "Seller", "Subscriber" };
foreach (string role in roles)
{
var roleStore = new RoleStore<IdentityRole>(context);
if (!context.Roles.Any(r => r.Name == role))
{
roleStore.CreateAsync(new IdentityRole(role));
}
}
var user = new ApplicationUser
{
FirstName = "XXXX",
LastName = "XXXX",
Email = "[email protected]",
NormalizedEmail = "[email protected]",
UserName = "Owner",
NormalizedUserName = "OWNER",
PhoneNumber = "+111111111111",
EmailConfirmed = true,
PhoneNumberConfirmed = true,
SecurityStamp = Guid.NewGuid().ToString("D")
};
if (!context.Users.Any(u => u.UserName == user.UserName))
{
var password = new PasswordHasher<ApplicationUser>();
var hashed = password.HashPassword(user,"secret");
user.PasswordHash = hashed;
var userStore = new UserStore<ApplicationUser>(context);
var result = userStore.CreateAsync(user);
}
AssignRoles(serviceProvider, user.Email, roles);
context.SaveChangesAsync();
}
public static async Task<IdentityResult> AssignRoles(IServiceProvider services, string email, string[] roles)
{
UserManager<ApplicationUser> _userManager = services.GetService<UserManager<ApplicationUser>>();
ApplicationUser user = await _userManager.FindByEmailAsync(email);
var result = await _userManager.AddToRolesAsync(user, roles);
return result;
}
}
在启动时运行此代码。在路由配置之后的配置方法末尾的 Startup.cs 中,添加以下代码,如 Stafford Williams 之前所说。
SampleData.Initialize(app.ApplicationServices);
您可以在 IdentityDbContext.cs 文件内的 OnModelCreating() 方法中播种用户和角色,如下所示。请注意,必须预定义密钥,以避免每次执行此方法时植入新的用户和角色。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//Seeding a 'Administrator' role to AspNetRoles table
modelBuilder.Entity<IdentityRole>().HasData(new IdentityRole {Id = "2c5e174e-3b0e-446f-86af-483d56fd7210", Name = "Administrator", NormalizedName = "ADMINISTRATOR".ToUpper() });
//a hasher to hash the password before seeding the user to the db
var hasher = new PasswordHasher<IdentityUser>();
//Seeding the User to AspNetUsers table
modelBuilder.Entity<IdentityUser>().HasData(
new IdentityUser
{
Id = "8e445865-a24d-4543-a6c6-9443d048cdb9", // primary key
UserName = "myuser",
NormalizedUserName = "MYUSER",
PasswordHash = hasher.HashPassword(null, "Pa$$w0rd")
}
);
//Seeding the relation between our user and role to AspNetUserRoles table
modelBuilder.Entity<IdentityUserRole<string>>().HasData(
new IdentityUserRole<string>
{
RoleId = "2c5e174e-3b0e-446f-86af-483d56fd7210",
UserId = "8e445865-a24d-4543-a6c6-9443d048cdb9"
}
);
}
public class YourDbContextSeedData
{
private YourDbContext _context;
public YourDbContextSeedData(YourDbContext context)
{
_context = context;
}
public async void SeedAdminUser()
{
var user = new ApplicationUser
{
UserName = "[email protected]",
NormalizedUserName = "[email protected]",
Email = "[email protected]",
NormalizedEmail = "[email protected]",
EmailConfirmed = true,
LockoutEnabled = false,
SecurityStamp = Guid.NewGuid().ToString()
};
var roleStore = new RoleStore<IdentityRole>(_context);
if (!_context.Roles.Any(r => r.Name == "admin"))
{
await roleStore.CreateAsync(new IdentityRole { Name = "admin", NormalizedName = "admin" });
}
if (!_context.Users.Any(u => u.UserName == user.UserName))
{
var password = new PasswordHasher<ApplicationUser>();
var hashed = password.HashPassword(user, "password");
user.PasswordHash = hashed;
var userStore = new UserStore<ApplicationUser>(_context);
await userStore.CreateAsync(user);
await userStore.AddToRoleAsync(user, "admin");
}
await _context.SaveChangesAsync();
}
在
ConfigureServices
类的
Startup.cs
方法中注册类型:
services.AddTransient<YourDbContextSeedData>();
接下来将
YourDbContextSeedData
类传递给
Configure
类的
Startup.cs
方法并使用它:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, YourDbContextSeedData seeder)
{
seeder.SeedAdminUser();
}
protected override void Seed(ApplicationDbContext context)
{
// This method will be called after migrating to the latest version.
string[] roles = new string[] { "Admin", "User" };
foreach (string role in roles)
{
if (!context.Roles.Any(r => r.Name == role))
{
context.Roles.Add(new IdentityRole(role));
}
}
//create user UserName:Owner Role:Admin
if (!context.Users.Any(u => u.UserName == "Owner"))
{
var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var user = new ApplicationUser
{
FirstName = "XXXX",
LastName = "XXXX",
Email = "[email protected]",
UserName = "Owner",
PhoneNumber = "+111111111111",
EmailConfirmed = true,
PhoneNumberConfirmed = true,
SecurityStamp = Guid.NewGuid().ToString("D"),
PasswordHash = userManager.PasswordHasher.HashPassword("secret"),
LockoutEnabled = true,
};
userManager.Create(user);
userManager.AddToRole(user.Id, "Admin");
}
context.SaveChanges();
}
IHostedService的概念。这使得运行异步后台成为可能Task
。@hamid-mosalla 的解决方案可以制作
async
并从
IHostedService
实现中调用。种子类实现可能类似于
public class IdentityDataSeeder
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<IdentityRole> _roleManager;
public IdentityDataSeeder(
UserManager<ApplicationUser> userManager,
RoleManager<IdentityRole> roleManager)
{
_userManager = userManager;
_roleManager = roleManager;
}
public async Task SeedAsync()
{
var superAdminRole = new IdentityRole
{
Id = "cac43a6e-f7bb-4448-baaf-1add431ccbbf",
Name = "SuperAdmin",
NormalizedName = "SUPERADMIN"
};
await CreateRoleAsync(superAdminRole);
var superAdminUserPassword = "P@ssword1";
var superAdminUser = new ApplicationUser
{
Id = "b8633e2d-a33b-45e6-8329-1958b3252bbd",
UserName = "[email protected]",
NormalizedUserName = "[email protected]",
Email = "[email protected]",
NormalizedEmail = "[email protected]",
EmailConfirmed = true,
};
await CreateUserAsync(superAdminUser, superAdminUserPassword);
var superAdminInRole = await _userManager.IsInRoleAsync(superAdminUser, superAdminRole.Name);
if (!superAdminInRole)
await _userManager.AddToRoleAsync(superAdminUser, superAdminRole.Name);
}
private async Task CreateRoleAsync(IdentityRole role)
{
var exits = await _roleManager.RoleExistsAsync(role.Name);
if (!exits)
await _roleManager.CreateAsync(role);
}
private async Task CreateUserAsync(ApplicationUser user, string password)
{
var exists = await _userManager.FindByEmailAsync(user.Email);
if (exists == null)
await _userManager.CreateAsync(user, password);
}
}
这可以从IHostedService
调用:
public class SetupIdentityDataSeeder : IHostedService
{
private readonly IServiceProvider _serviceProvider;
public SetupIdentityDataSeeder(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
using (var scope = _serviceProvider.CreateScope())
{
var seeder = scope.ServiceProvider.GetRequiredService<IdentityDataSeeder>();
await seeder.SeedAsync();
}
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
Startup
看起来像:
public void ConfigureServices(IServiceCollection services)
{
//...
services.AddHostedService<SetupIdentityDataSeeder>();
}
public static class ModelBuilderExtensions
{
public static void Seed(this ModelBuilder builder)
{
// Seed Roles
List<IdentityRole> roles = new List<IdentityRole>()
{
new IdentityRole { Name = "Admin", NormalizedName = "ADMIN" },
new IdentityRole { Name = "User", NormalizedName = "USER" }
};
builder.Entity<IdentityRole>().HasData(roles);
// -----------------------------------------------------------------------------
// Seed Users
var passwordHasher = new PasswordHasher<ApplicationUser>();
List<ApplicationUser> users = new List<ApplicationUser>()
{
// imporant: don't forget NormalizedUserName, NormalizedEmail
new ApplicationUser {
UserName = "[email protected]",
NormalizedUserName = "[email protected]",
Email = "[email protected]",
NormalizedEmail = "[email protected]",
},
new ApplicationUser {
UserName = "[email protected]",
NormalizedUserName = "[email protected]",
Email = "[email protected]",
NormalizedEmail = "[email protected]",
},
};
builder.Entity<ApplicationUser>().HasData(users);
///----------------------------------------------------
// Seed UserRoles
List<IdentityUserRole<string>> userRoles = new List<IdentityUserRole<string>>();
// Add Password For All Users
users[0].PasswordHash = passwordHasher.HashPassword(users[0], "User.123");
users[1].PasswordHash = passwordHasher.HashPassword(users[1], "User.155");
userRoles.Add(new IdentityUserRole<string> { UserId = users[0].Id, RoleId =
roles.First(q => q.Name == "User").Id });
userRoles.Add(new IdentityUserRole<string> { UserId = users[1].Id, RoleId =
roles.First(q => q.Name == "Admin").Id });
builder.Entity<IdentityUserRole<string>>().HasData(userRoles);
}}
public class AppDbContext : IdentityDbContext<ApplicationUser>
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
// Use seed method here
builder.Seed();
base.OnModelCreating(builder);
}}
app.SeedUsersAndRoles();
来自startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity;
namespace MyApplication.Models
{
public static class DataSeeder
{
public static async void SeedUsersAndRoles(this IApplicationBuilder app)
{
var context = app.ApplicationServices.GetService<ApplicationDbContext>();
UserWithRoles[] usersWithRoles = {
new UserWithRoles("Admin", new string[] { "Administrator" , "Distributor" },"somepassword"),//user and optional roles and password you want to seed
new UserWithRoles("PlainUser"),
new UserWithRoles("Jojo",new string[]{"Distributor" }) //seed roles to existing users (e.g. facebook login).
};
foreach (var userWithRoles in usersWithRoles)
{
foreach (string role in userWithRoles.Roles)
if (!context.Roles.Any(r => r.Name == role))
{
var roleStore = new RoleStore<IdentityRole>(context);
await roleStore.CreateAsync(new IdentityRole(role));
}
var ExistingUser = context.Users.FirstOrDefault(p => p.NormalizedUserName == userWithRoles.User.NormalizedUserName);
if (ExistingUser == null) //the following syntax: !context.Users.FirstOrDefault(p => p.NormalizedUserName == userWithRoles.User.NormalizedUserName))
//provokes execption:(ExecuteReader requires an open and available Connection.)
await new UserStore<ApplicationUser>(context).CreateAsync(userWithRoles.User);
await app.AssignRoles(userWithRoles); //assign also to existing users.
}
context.SaveChangesAsync();
}
public static async Task<IdentityResult> AssignRoles(this IApplicationBuilder app, UserWithRoles uWR)
{
UserManager<ApplicationUser> _userManager = app.ApplicationServices.GetService<UserManager<ApplicationUser>>();
ApplicationUser user = await _userManager.FindByNameAsync(uWR.User.NormalizedUserName);
var result = await _userManager.AddToRolesAsync(user, uWR.Roles);
return result;
}
}
public class UserWithRoles
{
private ApplicationUser user;
public ApplicationUser User { get { return user; } }
public string[] Roles { get; set; }
public UserWithRoles(string name, string[] roles = null, string password = "secret")
{
if (roles != null)
Roles = roles;
else
Roles = new string[] { };
user = new ApplicationUser
{
Email = name + "@gmail.com", NormalizedEmail = name.ToUpper() + "@GMAIL.COM",
UserName = name, NormalizedUserName = name.ToUpper(),
PhoneNumber = "+1312341234",
EmailConfirmed = true,
PhoneNumberConfirmed = true,
SecurityStamp = Guid.NewGuid().ToString("D"),
};
user.PasswordHash = new PasswordHasher<ApplicationUser>().HashPassword(user, password);
}
}
}
public class Seed
{
public static async Task Initialize(IServiceProvider serviceProvider, IConfiguration configuration)
{
var usrName = configuration.GetSection("Admin").GetSection("UserName").Value;
var email = configuration.GetSection("Admin").GetSection("Email").Value;
var pass = configuration.GetSection("Admin").GetSection("Pass").Value;
var roles = new string[4] { OWNER, ADMIN, SENIOR, USER };
if(await CreateUser(serviceProvider, email, usrName, pass, roles))
{
await AddToRoles(serviceProvider, email, roles);
}
}
private static async Task<bool> CreateUser(IServiceProvider serviceProvider, string email, string usrName, string pass, string[] roles)
{
var res = false;
using (var scope = serviceProvider.CreateScope())
{
var context = scope.ServiceProvider.GetService<BaseContext>();
if (!context.ApplicationUsers.Any(u => u.NormalizedUserName == usrName.ToUpper()))
{
var roleStore = scope.ServiceProvider.GetService<RoleManager<IdentityRole>>();
foreach (string role in roles)
{
if (!context.Roles.Any(r => r.Name == role))
{
await roleStore.CreateAsync(new IdentityRole(role)).ConfigureAwait(false);
}
}
var user = new ApplicationUser
{
UserName = usrName,
Email = email,
EmailConfirmed = true,
NormalizedEmail = email.ToUpper(),
NormalizedUserName = usrName.ToUpper(),
PhoneNumber = null,
PhoneNumberConfirmed = true,
SecurityStamp = Guid.NewGuid().ToString()
};
var password = new PasswordHasher<ApplicationUser>();
user.PasswordHash = password.HashPassword(user, pass); ;
var userStore = new UserStore<ApplicationUser>(context);
res = (await userStore.CreateAsync(user).ConfigureAwait(false)).Succeeded;
}
return res;
}
}
private static async Task AddToRoles(IServiceProvider serviceProvider, string email, string[] roles)
{
using (var scope = serviceProvider.CreateScope())
{
var userManager = scope.ServiceProvider.GetService<UserManager<ApplicationUser>>();
var usr = await userManager.FindByEmailAsync(email).ConfigureAwait(false);
await userManager.AddToRolesAsync(usr, roles).ConfigureAwait(false);
}
}
}
您可以简单尝试以下方法。
modelBuilder.Entity<IdentityUser>().HasData(
new IdentityUser { Id= "-1", UserName="sagark",PasswordHash="sagark", Email="emailid goes here" }
);
用以下内容替换要填充的此列:
RoleManager<IdentityRole> roleManager = serviceProvider.GetService<RoleManager<IdentityRole>>();
roleManager.CreateAsync(new IdentityRole(role));
通过使用扩展方法。
namespace Course.Repository.Utilities {
public static class AddRoleToAdmin {
public static void ConfigurationUserAndRole(this ModelBuilder modelBuilder)
{
//Seeding a 'Administrator' role to AspNetRoles table
modelBuilder.Entity<IdentityRole>().HasData(
new IdentityRole()
{
Id = "2c5e174e-3b0e-446f-86af-483d56fd7210",
Name = "Admin",
NormalizedName = "Admin".ToUpper()
}
);
var hasher = new PasswordHasher<IdentityUser>();
// Seeding the User to AspNetUsers table
modelBuilder.Entity<AppUser>().HasData(
new AppUser()
{
Id= "8e445865-a24d-4543-a6c6-9443d048cdb9",
UserName = "[email protected]",
Email = "[email protected]",
NormalizedUserName = "[email protected]".ToUpper(),
NormalizedEmail = "[email protected]".ToUpper(),
PasswordHash = hasher.HashPassword(null, "Admin123"),
EmailConfirmed = true,
LockoutEnabled = true,
PhoneNumberConfirmed = true,
SecurityStamp = Guid.NewGuid().ToString()
}
);
//Seeding the relation between our user and role to AspNetUserRoles table
modelBuilder.Entity<IdentityUserRole<string>>().HasData(
new IdentityUserRole<string>()
{
RoleId= "2c5e174e-3b0e-446f-86af-483d56fd7210", // 2c5e174e-3b0e-446f-86af-483d56fd7210
UserId = "8e445865-a24d-4543-a6c6-9443d048cdb9" // 8e445865-a24d-4543-a6c6-9443d048cdb9
}
);
}
}
}
在 DbContext 中创建模型
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Call Extension Method.
modelBuilder.ConfigurationUserAndRole();
}
https://github.com/nguyentuananh921/Learning.git 谢谢