一、ASP.NET Core Identity概要
ASP.NET Core Identity的原理可以看ASP.NET Core 之 Identity 入门(一),讲的通俗易懂,这里主要通过示例使用ASP.NET Core Identity。
二、ASP.NET Core Identity示例
1、创建具有身份验证的 Web 应用
- 选择 " 文件" " > 新建 > 项目"。
- 选择“ASP.NET Core Web 应用程序”。 将项目命名为 WebApp1 ,使其命名空间与项目下载相同。 单击" 确定"。
- 选择 ASP.NET Core Web 应用程序,然后选择 " 更改身份验证"。
- 选择 单个用户帐户 ,然后单击 "确定"。
2、项目结构
因为我们创建项目的时候选择了个人账户,所以默认是基于 Microsoft.EntityFrameworkCore 的 ORM 框架来操作数据库的。
(1) ApplicationDbContext文件解析
我们先打开【Data -> Migrations -> ApplicationDbContext】
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; namespace IdentityAuthentication.Data { public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } } }
微软已经定义好了一个可扩展的 DbContext 对象,默认命名叫 ApplicationDbContext(名称可根据自己的需要进行更改)。这里面没有任何 DbSet 属性或者相关的 EntityTypeConfiguretion 配置,那它的表结构是怎样的呢?看下父类 IdentityDbContext :
发现它集成了 IdentityDbContext 基类,还定义了泛型的类型,IdentityUser 和 IdentityRole 就是我们的实体了,一个是用户,一个是角色。但还是没有 DbSet 属性,所以我们接着看下泛型基类IdentityDbContext:
发现这里又做了一次封装,接着往下找:
终于看到了DbSet,所以当你在使用 ApplicationDbContext
时,你就可以对用户和角色以及相关的 DbSet 进行操作了。
(2)Startup.cs文件
ConfigureServices
中配置如下:
public void ConfigureServices(IServiceCollection services) { #region 第一部分 EFCore服务注入 //EFCore迁移 https://www.cnblogs.com/qtiger/p/14581446.html services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); //数据库异常捕获 services.AddDatabaseDeveloperPageExceptionFilter(); #endregion #region 第二部分 Identity服务注入 services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>(); services.Configure<IdentityOptions>(options => { // Password settings. //PasswordOptions 类 https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.identity.passwordoptions?view=aspnetcore-5.0 options.Password.RequireDigit = true;//密码是否必须包含数字 options.Password.RequireLowercase = true;//密码是否包含小写ASCII字符 options.Password.RequireNonAlphanumeric = true;//密码是否必须非字母数字字符 options.Password.RequireUppercase = true;//密码是否包含大写字母ASCII字符 options.Password.RequiredLength = 6;//密码最小长度,默认6 options.Password.RequiredUniqueChars = 1;//密码必须包含唯一字符的最小数目,默认1 // Lockout settings. //LockoutOptions 类 https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.identity.lockoutoptions?view=aspnetcore-5.0 options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);//在 TimeSpan 发生锁定时用户被锁定的。 默认为5分钟。 options.Lockout.MaxFailedAccessAttempts = 5;//在用户被锁定之前允许的失败访问尝试次数,假设已启用锁定。 默认值为5。 options.Lockout.AllowedForNewUsers = true;//是否锁定新用户 // User settings. // UserOptions 类 https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.identity.useroptions?view=aspnetcore-5.0 options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";//用于验证用户名的用户名中允许使用的字符的列表 options.User.RequireUniqueEmail = false;//指示应用程序是否需要为其用户提供唯一的电子邮件 }); #endregion #region 第三部分 应用程序cookie配置 //CookieAuthenticationOptions 类 https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.authentication.cookies.cookieauthenticationoptions?view=aspnetcore-5.0 services.ConfigureApplicationCookie(options => { // Cookie settings options.Cookie.HttpOnly = true;//确定浏览器是否应允许客户端 javascript 访问 cookie。 默认值为 true,这表示只将 Cookie 传递给 http 请求,而不可供页上的脚本使用。 options.ExpireTimeSpan = TimeSpan.FromMinutes(5);//控制 cookie 中存储的身份验证票证从其创建的点保持有效的时间 options.LoginPath = "/Identity/Account/Login";//如果为 LogoutPath 提供了处理程序,则对该路径的请求将基于 ReturnUrlParameter 进行重定向。 options.AccessDeniedPath = "/Identity/Account/AccessDenied";//处理 ForbidAsync 时,重定向目标的处理程序使用 AccessDeniedPath 属性。 options.SlidingExpiration = true;//SlidingExpiration 设置为 true,以指示处理程序在每次处理超过过期时段一半的请求时,使用新的过期时间重新颁发新的 cookie。 }); #endregion #region 第四部分 注入页面相关的服务 services.AddRazorPages(); #endregion }
- 先来看下第一部分EFCore迁移,因为该项目框架默认是基于 Microsoft.EntityFrameworkCore 的 ORM 框架来操作数据库的,所以需要注入EFCore相关的服务。
- 重点是第二部分Identity服务。AddDefaultIdentity 是在 ASP.NET Core 2.1 中引入的,注入认证相关的服务,向应用程序添加一组通用认证服务,包括默认 UI、令牌提供程序,并将身份验证配置为cookie。 调用
AddDefaultIdentity
类似于调用以下内容:
AddEntityFrameworkStores表示添加认证信息存储的实体框架实现,即认证信息通过efcore存储。services.Configure<IdentityOptions>(options =>{})用于配置认证信息,上边代码中有详细的注释,这里就不说了。
- 第三部分是对cookie的设置,可以看下代码注释。
- 这里详细说下第四部分,在netcore项目中经常见到AddMvcCore,AddControllers,AddControllersWithViews,AddRazorPages,他们有什么不一样的吗?
- services.AddMvcCore() 只注册路由请求和执行控制器所必要的核心服务,确保 Pipeline 程序可运转。除非是有能力并想完全去自主DIY,一般不建议直接使用这个。
- services.AddControllers()除包含了 AddMvcCore() 所有功能,再加上:Authorization、ApiExplorer、Data Annotation、Formatter Mapping、CORS。要用 Controller 但不用View,新建WebAPI时,默认采用的就是这个,使用这个时,与SwashBuckle配合时,无需再额外引入ApiExplorer,自身已经依赖。
- services.AddRazorPages() 包含 AddMvcCore() 所有功能,再加上:Razor Pages、Authorization、Data Annotation、Cache Tag Helper
- 包含 AddControllers() 所有功能,再加上:cshtml和Razor View、Cache Tag Helper,标准MVC模式,常用Razor视图,使用这个就够了
- services.AddMvc() 包含 AddControllersWithViews() 及 AddRazorPages() 功能。 包含的功能最为齐全,如果不想遗漏功能,直接使用这个就行
Configure中的配置:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseMigrationsEndPoint(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); }
3、应用迁移
先在appsettings.json配置下数据库连接字符串:
{
"ConnectionStrings": {
"DefaultConnection": "Server=.;Database=DbIdentity;User ID=sa;Password=123456;"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
在包管理器控制台中运行以下命令 (PMC) :
PM> Update-Database
查看下本地数据库:
4、运行效果
三、参考资料
2、https://www.cnblogs.com/savorboard/p/aspnetcore-identity.html