Part5 – (1) Identity标识框架1
1、Authentication对访问者的用户身份进行验证,“用户是否登录成功”。
2、Authorization验证访问者的用户身份是否有对资源访问的访问权限,“用户是否有权限访问这个地址”。
标识(Identity)框架
1、标识(Identity)框架:采用基于角色的访问控制(Role-Based Access Control,简称RBAC)策略,内置了对用户、角色等表的管理以及相关的接口,支持外部登录、2FA等。
2、标识框架使用EF Core对数据库进行操作,因此标识框架支持几乎所有数据库。
Identity框架使用
1、IdentityUser<TKey>、IdentityRole<TKey>,TKey代表主键的类型。我们一般编写继承自IdentityUser<TKey>、IdentityRole<TKey>等的自定义类,可以增加自定义属性。
2、NuGet安装Microsoft.AspNetCore.Identity.EntityFrameworkCore, Microsoft.EntityFrameworkCore.SqlServer, Tools;
3、创建继承自IdentityDbContext的类
4、可以通过IdDbContext类来操作数据库,不过框架中提供了RoleManager、UserManager等类来简化对数据库的操作。
5、部分方法的返回值为Task<IdentityResult>类型,查看、讲解IdentityResult类型定义。
6、向依赖注入容器中注册标识框架相关的服务
主要步骤:
using Microsoft.AspNetCore.Identity;
namespace Part5_1
{
public class MyUser:IdentityUser<long>
{
}
}
using Microsoft.AspNetCore.Identity;
namespace Part5_1
{
public class MyRole:IdentityRole<long>
{
}
}
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace Part5_1
{
public class MyDbContext : IdentityDbContext<MyUser,MyRole,long>
{
public MyDbContext(DbContextOptions<MyDbContext> options)
:base(options)
{
}
}
}
builder.Services.AddDbContext<MyDbContext>(opt => {
string connStr = builder.Configuration.GetConnectionString("Default");
opt.UseSqlServer(connStr);
});
builder.Services.AddDataProtection();
builder.Services.AddIdentityCore<MyUser>(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(MyUser), typeof(MyRole), builder.Services);
idBuilder.AddEntityFrameworkStores<MyDbContext>()
.AddDefaultTokenProviders().AddRoleManager<RoleManager<MyRole>>()
.AddUserManager<UserManager<MyUser>>();
Part5 – (2) Identity标识框架2
7、执行Add-Migration、Update-Database等命令执行EF Core的数据库迁移。
8、通过RoleManager、UserManager等来进行数据操作。比如创建角色、创建用户。
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
namespace Part5_1.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class UserRoleController : ControllerBase
{
private readonly UserManager<MyUser> userManager;
private readonly RoleManager<MyRole> roleManager;
public UserRoleController(UserManager<MyUser> userManager, RoleManager<MyRole> roleManager)
{
this.userManager = userManager;
this.roleManager = roleManager;
}
[HttpPost]
public async Task<ActionResult<string>> Test1()
{
bool roleExists = await roleManager.RoleExistsAsync("admin");
if (!roleExists)
{
MyRole role = new MyRole { Name = "Admin" };
var r = await roleManager.CreateAsync(role);
if (!r.Succeeded) return BadRequest(r.Errors);
}
MyUser user = await this.userManager.FindByNameAsync("zcq");
if (user == null)
{
user = new MyUser { UserName = "zcq", Email = "zcq@gmail.com", EmailConfirmed = true };
var r = await userManager.CreateAsync(user, "123456");
if (!r.Succeeded) return BadRequest(r.Errors);
if (!await userManager.IsInRoleAsync(user,"admin"))
{
r = await userManager.AddToRoleAsync(user, "admin");
}
}
return Ok();
}
}
}
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
namespace Part5_1.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class UserRoleController : ControllerBase
{
private readonly UserManager<MyUser> userManager;
private readonly RoleManager<MyRole> roleManager;
public UserRoleController(UserManager<MyUser> userManager, RoleManager<MyRole> roleManager)
{
this.userManager = userManager;
this.roleManager = roleManager;
}
[HttpPost]
public async Task<ActionResult> CheckPwd(CheckPwdRequest req)
{
string userName = req.UserName;
string password = req.Password;
var user = await userManager.FindByNameAsync(userName);
if (user == null)
return NotFound($"用户名不存在{userName}");//容易造成安全风险
if (await userManager.IsLockedOutAsync(user))//判断是否锁定
return BadRequest("LockedOut 锁定结束时间" + user.LockoutEnabled);
var success = await userManager.CheckPasswordAsync(user, password);
if (success)
{
await userManager.ResetAccessFailedCountAsync(user);
return Ok("Success");
}
else
{
await userManager.AccessFailedAsync(user);
return BadRequest("Failed 用户名或者密码错误" );
}
}
}
}
本文版权归个人技术分享站点所有,发布者:chaoqiang,转转请注明出处:http://www.zhengchaoqiang.com/1578.html