在创建授权数据种子前,先创建一个用户角色的枚举。
public enum UserRole
{
Admin,
Teacher
}
这里定义了2个角色,分别是管理员和教师。
创建一个IdentityDataSeeder类,并在类中创建Seed方法,用于生成角色和用户。
如果不存在角色,则创建枚举中的2个角色。
如果不存在用户,则分别创建1个管理员用户和教师用户。
代码如下:
public class IdentityDataSeeder(UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager)
{
public async Task Seed()
{
if (!roleManager.Roles.Any())
{
await roleManager.CreateAsync(new IdentityRole(UserRole.Admin.ToString()));
await roleManager.CreateAsync(new IdentityRole(UserRole.Teacher.ToString()));
}
if (!userManager.Users.Any())
{
IdentityUser user1 = new IdentityUser { UserName = "root" };
await userManager.CreateAsync(user1, "123456");
await userManager.AddToRoleAsync(user1, UserRole.Admin.ToString());
IdentityUser user2 = new IdentityUser { UserName = "Nyazira" };
await userManager.CreateAsync(user2, "123456");
await userManager.AddToRoleAsync(user2, UserRole.Teacher.ToString());
}
}
}
在这里,我们注入了UserManager<IdentityUser>
和RoleManager<IdentityRole>
的实例。
其中RoleManager用于创建角色,UserManager用于创建用户并给用户授权。
IdentityRole和IdentityUser分别是角色和用户的模型。
RoleManager通过CreateAsync方法创建角色。
UserManager也通过CreateAsync方法创建用户,并通过AddToRoleAsync给用户授予相应的角色。
虽然这个方法已经写完,但是却无法使用,原因是框架没办法注入UserManager和RoleManager的实例。
它们的实例需要手动添加。
services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<AppDbContext>();
通过AddIdentity方法可以添加授权服务,并通过AddEntityFrameworkStores方法指定角色和用户数据存储的位置。
我们在Seed方法中设置的密码非常简单,这样的密码是无法通过默认密码规则的。
可以通过设置修改密码规则,代码如下:
services.Configure<IdentityOptions>(options =>
{
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 3;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequireDigit = false;
});
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 3;
options.Password.RequireNonAlphanumeric = false;
false
,表示密码中不需要包含特殊字符(如@
、#
等)。options.Password.RequireLowercase = false;
false
,表示密码中不需要包含小写字母。options.Password.RequireUppercase = false;
false
,表示密码中不需要包含大写字母。options.Password.RequireDigit = false;
false
,表示密码中不需要包含数字。services.AddTransient<IdentityDataSeeder>();
using (var scope = app.Services.CreateScope())
{
var serviceProvider = scope.ServiceProvider;
var identityDataSeeder = serviceProvider.GetRequiredService<IdentityDataSeeder>();
identityDataSeeder.Seed().Wait();
}
最终Main方法中的代码如下:
var builder = WebApplication.CreateBuilder(args);
IServiceCollection services = builder.Services;
services.AddControllersWithViews();
services.AddDbContext<AppDbContext>();
services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<AppDbContext>
services.Configure<IdentityOptions>(options =>
{
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 3;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequireDigit = false;
});
services.AddScoped<MajorRepo>();
services.AddScoped<GradeRepo>();
services.AddScoped<ClassRepo>();
services.AddScoped<StudentRepo>();
services.AddScoped<MajorService>();
services.AddScoped<GradeService>();
services.AddScoped<ClassService>();
services.AddScoped<StudentService>();
services.AddScoped<SearchService>();
services.AddTransient<IdentityDataSeeder>();
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var serviceProvider = scope.ServiceProvider;
var identityDataSeeder = serviceProvider.GetRequiredService<IdentityDataSeeder>();
identityDataSeeder.Seed().Wait();
}
app.UseStatusCodePagesWithReExecute("/error/{0}");
app.UseStaticFiles();
app.MapDefaultControllerRoute();
app.Run();
重启项目后,打开数据库,查看AspNetRoles和AspNetUsers两张表,会发现里面添加了2个角色和2个用户,且用户的密码已做混淆处理。