我们之前讲解关于Asp.Net Core Identity的使用,总共有12篇文章,如果错过的小伙伴可以看这里,github地址如下:https://github.com/bingbing-gui/AspNetCore-Skill
ASP.NET Core Identity 是一个附加层,随 ASP.NET Core 一起发布,在 ASP.NET Core 应用程序中管理用户账户提供了多种服务。这包括每个服务的抽象和默认实现。
DataModel—ASP.NET Core Identity 模型的基本类型。包括 IdentityUser 和 IdentityRole 等类型。
Stores—用于存储和检索数据模型类型实例的持久层。包括 IUserStore<> 和 IRoleStore<> 等接口,以及一系列细粒度的接如 IUserPasswordStore<>、IUserAuthenticatorKeyStore<> 等。
Managers—在存储之上提供服务层以管理用户,有点类似于仓储层。有三个主要的抽象:
UserManager—对用户执行相对高级的操作,例如通过用户名和电子邮件创建用户,处理密码哈希、生成规范化名称、更新安全戳等。
RoleManager—类似于 UserManager,执行与角色相关的高级操作,例如添加或移除角色的声明。
SignInManager—提供用于用户登录和注销、验证双因素代码、检查账户锁定等的高级 API。
Managers提供了相对高级的 API 用于与 Identity 进行交互,但你仍然需要实际调用Managers接口才能使用它们。例如,为了帮你完成这个阶段,微软长期提供了一个默认的 UI 包,Microsoft.AspNetCore.Identity.UI,其中包含了超过 30 个用于处理 Identity 的 Razor Pages。这些页面包括登录和注销页面、更改电子邮件和密码的页面、启用和管理双因素认证(2FA)代码的页面等。
默认 UI 添加的大量代码为你节省了编写代码的时间。你可以使用脚手架工具(如上所示)将这些代码导入到你的应用中,当然你也可以将UI层扔掉,在自己的MVC里面重新实现这些功能,也可以将他们封装成web api,这无疑加大了工作量。
不幸的是,这让你处于一个尴尬的境地。如果你想使用 ASP.NET Core Identity在应用内存储用户账户,你不得不选择以下三条主要路径之一:
使用默认的 Razor Pages UI样式。这意味着你只能使用默认的样式,除了可以在全局级别进行主题设置之外。这对于真正的商业项目不太理想。
使用默认的 Razor Pages UI,然后自定义 Razor 模板。你可以自定义自己的样式,但需要更新很多页面,并且保持脚手架代码的最新状态非常困难。 自己构建整个 UI,这带来了大量的工作,因为登录和账户页面可能是你的应用中最敏感的部分。
上面存在这么多问题,那我们需要解决这些问题,那么Identity API endpoints可以解决上面问题!
可以非常容易创建自己的UI,这使得应用的身份/账户 UI 样式与应用的其他部分保持一致。 你可以为 SPA 应用或移动应用颁发访问令牌,以便在调用 ASP.NET Core 应用中的其他 API 时使用。
然而Cookies在手机端是很难管理的,使用token是一个很好的选择。
dotnet add package Microsoft.EntityFrameworkCore.SQLite
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
配置EF Core
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options)
{
}
}
调用WebApplicationBuilder的AddDbContext<>来注册AppDbContext
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add EF Core
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection")));
{
"ConnectionStrings": {
"DefaultConnection": "Data Source=my_test_app.db"
}
}
创建一个从 IdentityUser 派生的类型 更新我们的 AppDbContext 继承自 IdentityDbContext<>
public class AppUser : IdentityUser
{
// Add customisations here later
}
public class AppDbContext : IdentityDbContext<AppUser>
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
}
AddIdentityApiEndpoints<>
方法添加 Identity 服务,并配置标准的 Identity EF Core 存储:builder.Services
.AddIdentityApiEndpoints<AppUser>()
.AddEntityFrameworkStores<AppDbContext>();
配置 Bearer 和 Cookie 认证 添加核心 Identity 服务,如 UserManager 添加 Identity API 端点所需的服务,如 SignInManager、令牌提供程序和一个无操作的 IEmailSender 实现
创建数据库
应用程序为了EF Core,我们需要创建一个migration并且更新数据库,如果你应用编译成功你能够通过下面两个步骤:
dotnet ef migrations add InitialSchema
dotnet ef database update
最终,我们希望能够通过授权来保护我们的 API,因此为了确保这一点正常工作,让我们在天气预报端点添加一个授权要求:
[HttpGet(Name = "GetWeatherForecast")]
[Authorize]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
Identity api终结点地址
在 WebApplication 上调用 MapIdentityApi<> 将 Identity 端点添加到你的应用程序中。这将为你的应用程序添加各种端点。
app.MapGroup("/account").MapIdentityApi<AppUser>();
查看Identity api
我们请求WeatherForecast接口获取到401状态码,说明没有权限
注意这里password必须满足IdentityOptions 标准的需求,包含长度和复杂度。
查看Token
调用受保护api
我们现在有access_token,我们能够使用它调用受保护的API: