一、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