Identity框架

Identity框架是用来验证用户的身份和权限的

框架采用基于用基于角色访问控制(Role-based access control-简称RBAC)的策略,内置了对用户、角色等表的管理和相关接口。

该框架使用EFCore操作数据库,所以EFCore支持的数据库,Identity框架也支持。

概念:一个应用一般都有用户登录,然后每个用户可能有多种权限,比如VIP,超级VIP,管理员等等。

权限用Role(角色)表示,一个用户可以有多个角色,这样就可以根据用户不同的角色来判断该用户可以使用哪些功能。

Authentication 和 Authorization

1.Authentication :验证用户身份,"是否登录成功"

2.Authorization :验证用户的权限,用户是否具有管理员(VIP)等权限

使用

1.首先Nuget包安装:Microsoft.AspNetCore.Identity.EntityFrameworkCore

2.一般新建User和Role两个类,分别继承IdentityUser<Tkey>,IdentityRole<Tkey>,泛型 Tkey 代表主键。

可以添加自定义属性

public class MyUser:IdentityUser<long>
{
//可以添加自定义属性
public string QQNumber { get; set; }
}
public class MyRole:IdentityRole<long>
{
}

3.新建一个类继承IdentityDbContext把自定义User和Role添加进泛型

public class MyDbContext:IdentityDbContext<MyUser,MyRole,long>
{
public MyDbContext(DbContextOptions options)
: base(options)
{
}
}

然后就是EFcore的操作了,这里使用的是sqlite。

nuget安装2个包:Microsoft.EntityFrameworkCore.Sqlit

Microsoft.EntityFrameworkCore.Tools

在program添加以下代码:

builder.Services.AddDbContext<MyDbContext>(option => {
option.UseSqlite("Data Source = MyIdentity.db");
});
builder.Services.AddDataProtection();
builder.Services.AddIdentityCore<MyUser>(option => {
option.Password.RequireDigit = false;//设置密码必须为数字
option.Password.RequireLowercase = false;
option.Password.RequireNonAlphanumeric = false;
option.Password.RequireUppercase = false;
option.Password.RequiredLength = 8;//设置密码长度必须为8等等
option.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
option.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
});
var identityBuider = new IdentityBuilder(typeof(MyUser), typeof(MyRole), builder.Services);
identityBuider.AddEntityFrameworkStores<MyDbContext>()
.AddDefaultTokenProviders().AddRoleManager<RoleManager<MyRole>>()
.AddUserManager<UserManager<MyUser>>();

然后在程序包管理器控制台执行迁移和更新数据库:1.Add-Migration init 2.uptate-database

4.一般不通过DbContext操作,通过RoleManager和UserManager等来进行数据库操作

//代码中的userManager等都已通过依赖注入

创建一个用户

var user = await userManager.FindByNameAsync("李四");
if (user == null) {
var u = new MyUser {
UserName = "李四",
QQNumber="5464645456"
};
var result= await userManager.CreateAsync(u,"Pwd123456");
if(result.Succeeded)
{
//创建成功
//为该用户添加一个角色
await userManager.AddToRoleAsync(u, "admin");
}
}

创建一个角色:

var roleExists = await roleManager.RoleExistsAsync("Admin");
if(roleExists == null)
{
MyRole myRole=new MyRole() { Name="Admin"};
await roleManager.CreateAsync(myRole);
}

检查用户

var user = await userManager.FindByNameAsync(name);
if (user == null)
{
return BadRequest("用户名不存在");
}
//检查账号是否被锁
if (await userManager.IsLockedOutAsync(user))
{
return BadRequest("账号被锁了");
}
//检查密码
var success = await userManager.CheckPasswordAsync(user,password);
if (success)
{
//重置登录失败的次数
await userManager.ResetAccessFailedCountAsync(user);
return Ok();
}
else
{
//登录失败次数加1,达到一定次数用户被锁
await userManager.AccessFailedAsync(user);
return BadRequest();
}

判断用户是否拥有Admin角色(权限)

if (await userManager.IsInRoleAsync(user, "Admin"))
{
return Ok("Admin");
}

重置密码:

Token一般是通过邮件等返回给用户,然后用户输入通过验证后再重置

var user =await userManager.FindByNameAsync(name);
if (user != null)
{
//生成Token
var token = await userManager.GeneratePasswordResetTokenAsync(user);
//重置密码
await userManager.ResetPasswordAsync(user,token,"newPasswoed");
return Ok();
}

当然很有很多没写到