【Identity】入门
ASP.NET Core Identity
下文简称Identity,可以理解为用户管理系统,那么它自然是十分强大的,包含用户管理的方方面面,简单的来讲包括:
- 用户数据存储(使用EF Core对数据库进行操作,因此Identity框架支持几乎所有数据库。)
- 登陆、注册外加身份认证(基于cookie的身份认证,如果你使用Vs那么还可以生成用于注册登录的用户界面及处理代码)
- 角色管理
- 基于声明的认证模式Claims Based Authentication
Identity框架使用
1、安装Nuget包
<PackageReference Include="IdentityModel" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.5">
2、定义用户和角色
IdentityUser<TKey>、IdentityRole<TKey>。分别代表用户、角色。TKey代表主键的类型。
我们一般编写继承自IdentityUser
public class MyIdentityUser : IdentityUser<int>
{
/// <summary>
/// 新增属性,班级ID
/// </summary>
public int ClassID { get; set; }
}
public class MyIdentityRole : IdentityRole<int>
{
}
3、创建继承自IdentityDbContext的类
public class MyIdentityContext : IdentityDbContext<MyIdentityUser, MyIdentityRole, int>
{
public MyIdentityContext(DbContextOptions<MyIdentityContext> options) : base(options)
{ }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
}
}
4、添加数据库连接配置
{
"ConnectionStrings": {
"Default": "Server=.;Database=IdentityDB;User ID=sa;Password=123456;"
}
}
5、注册Identity
IServiceCollection services = builder.Services;
string connStr = builder.Configuration.GetConnectionString("Default");
services.AddDbContext<MyIdentityContext>(opt => {
opt.UseSqlServer(connStr);
});
services.AddDataProtection();
services.AddIdentityCore<MyIdentityUser>(options => { //注意不是AddIdentity
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequiredLength = 6;
options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
});
var idBuilder = new IdentityBuilder(typeof(MyIdentityUser), typeof(MyIdentityRole), services);
idBuilder.AddEntityFrameworkStores<MyIdentityContext>()
.AddDefaultTokenProviders()
.AddRoleManager<RoleManager<MyIdentityRole>>()
.AddUserManager<UserManager<MyIdentityUser>>();
6、创建迁移文件
Add-Migration
7、自动迁移、添加种子数据
/// <summary>
/// 应用迁移、添加种子数据
/// </summary>
/// <param name="serviceProvider"></param>
/// <exception cref="Exception"></exception>
public static void EnsureSeedData(ServiceProvider serviceProvider)
{
var services = new ServiceCollection();
using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = scope.ServiceProvider.GetService<MyIdentityContext>();
context.Database.Migrate();
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<MyIdentityUser>>();
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<MyIdentityRole>>();
IdentityResult result;
//角色
bool exist = roleManager.RoleExistsAsync("Admin").Result;
if (!exist)
{
//添加角色
var role = new MyIdentityRole
{
Name = "Admin",
NormalizedName = "系统管理员"
};
result = roleManager.CreateAsync(role).Result;
if (!result.Succeeded)
{
throw new Exception(result.Errors.First().Description);
}
//添加角色声明
result = roleManager.AddClaimAsync(role, new Claim(JwtClaimTypes.Role, "Admin")).Result;
if (!result.Succeeded)
{
throw new Exception(result.Errors.First().Description);
}
}
//用户
var user = userManager.FindByNameAsync("fan").Result;
if (user == null)
{
user = new MyIdentityUser
{
UserName = "fan",
Email = "410577910@qq.com",
ClassID = 22
};
//添加用户
result = userManager.CreateAsync(user, "123456").Result;
if (!result.Succeeded)
{
throw new Exception(result.Errors.First().Description);
}
//添加用户声明
result = userManager.AddClaimsAsync(user, new Claim[] {
new Claim(JwtClaimTypes.Name, "fan"),
new Claim(JwtClaimTypes.GivenName, "fan"),
new Claim(JwtClaimTypes.FamilyName, "fan"),
new Claim(JwtClaimTypes.Email, "410577910@qq.com"),
new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean),
new Claim(JwtClaimTypes.WebSite, "http://fan.com"),
new Claim(JwtClaimTypes.Address, @"{ '城市': '北京', '邮政编码': '10000' }")
}).Result;
if (!result.Succeeded)
{
throw new Exception(result.Errors.First().Description);
}
//用户添加角色
result = userManager.AddToRoleAsync(user, "Admin").Result;
if (!result.Succeeded)
{
throw new Exception(result.Errors.First().Description);
}
}
}
}
在program中调用SeedData.EnsureSeedData(provider)
部分方法的返回值为Task
8、查看数据库
数据库和数据都创建好了

9、实现登录、修改密码功能
可以通过IdDbContext类来操作数据库,不过框架中提供了RoleManager、UserManager等类来简化对数据库的操作。
// 登录提交
[HttpPost]
public async Task<IActionResult> Login([FromForm] string userName, [FromForm] string password)
{
var user = await _userManager.FindByNameAsync(userName);
if (user == null)
{
return NotFound($"用户名不存在{userName}");
}
if (await _userManager.IsLockedOutAsync(user))
{
return BadRequest("被锁定");
}
bool success = await _userManager.CheckPasswordAsync(user, password);
if (success)
{
await _userManager.ResetAccessFailedCountAsync(user);
return Ok("success");
}
else {
await _userManager.AccessFailedAsync(user);
return BadRequest("密码错误");
}
return View();
}
其他功能可以参考项目源码

浙公网安备 33010602011771号