Identity框架 笔记

发布时间 2023-08-04 02:05:59作者: hlc-川

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();
            }

当然很有很多没写到