.net 6.0 identity實現
這裡是用的現在最新的.net 6.0 ,其他版本都差不多,我這裡不是在建立專案那裡新增身份驗證,而是基於沒有身份驗證後期新增進去的。
可以去官網上面看,都有相關的文件:https://docs.microsoft.com/zh-cn/aspnet/core/security/authentication/identity?view=aspnetcore-6.0&tabs=netcore-cli
1. 引用NUGET包
這裡會設計到幾個包
Microsoft.AspNetCore.Identity : 包含Identity自帶的model類
Microsoft.Extensions.Identity.Stores : 包含了上面Identity的依賴項,新增了UserStore和RoleStore等操作項,我們看原始碼可以看出來
Microsoft.AspNetCore.Identity.EntityFrameworkCore :包含了上面Stores 的依賴項,還新增了IdentityDbContext的資料庫EF操作
由於是包含了依賴項,只需要在Domain實體層引用 efcore這個包就行了
Microsoft.AspNetCore.Identity.EntityFrameworkCore
2. 新增DbContext
Identity自帶了一些系統表,所以要生成資料庫,基礎設定層這裡的DbContext要繼承Identity提供的IdentityDbContext
3. 新增相關實體,如果不需要擴充套件Identity系統自帶的這些表,可以忽略這一步
這裡只是舉了一個例子,如果需要擴充套件其他資料表,只需要繼承相應的Idnetity實體就行了
3. 注入服務
我是基於mysql資料庫的,mysql相關的依賴項這裡就直接忽略了。
先配置EF DbContext生成資料庫
builder.Services.AddDbContext<TestIdentityDbContext>(options => { var strdb = builder.Configuration.GetSection("dbstr").Value; options.UseMySql(strdb, ServerVersion.AutoDetect(strdb), mySqlOptionsAction => { mySqlOptionsAction.MigrationsAssembly(typeof(Program).Assembly.GetName().Name); }); });
配置 Identity
builder.Services.AddIdentity<IdentityUser, IdentityRole>(options => { // Password settings. options.Password.RequireDigit = true; options.Password.RequireLowercase = true; options.Password.RequireNonAlphanumeric = true; options.Password.RequireUppercase = true; options.Password.RequiredLength = 6; options.Password.RequiredUniqueChars = 1; // Lockout settings. options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); options.Lockout.MaxFailedAccessAttempts = 5; options.Lockout.AllowedForNewUsers = true; // User settings. options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"; options.User.RequireUniqueEmail = false; }) .AddDefaultTokenProviders() .AddEntityFrameworkStores<TestIdentityDbContext>(); //配置授權跳轉 builder.Services.ConfigureApplicationCookie(cookie => { cookie.LoginPath = "/Account/FcbLogin/"; cookie.LogoutPath = "/Account/FcbLoginOut/"; cookie.AccessDeniedPath = "/Account/FcbError/"; cookie.ExpireTimeSpan = TimeSpan.FromMinutes(30); // cookie.SlidingExpiration = true; });
順便提一下,一般授權會注入Authentication,但是idnetity 內部已經呼叫了AddAuthentication,所以這裡不需要呼叫
4. 注入管道
在UseAuthorization之前注入UseAuthentication
app.UseAuthentication();
5. 新增授權
新增登入和登出,我這裡只是簡單測試,只是寫了登入相關的東西
public ActionResult FcbLogin(string ReturnUrl) { ReturnUrl = ReturnUrl ?? Url.Content("~/"); ViewBag.ReturnUrl = ReturnUrl; return View(); } [HttpPost] public async Task<ActionResult> Login(UserLogin model) { var UserLoginInfo = await _userManager.FindByNameAsync(model.UserName); if (UserLoginInfo == null) { var user = new aspnetusers(model.UserName, model.Password); var result = await _userManager.CreateAsync(user); if (result.Succeeded) { _logger.LogInformation("註冊成功"); Console.WriteLine("註冊成功"); } else { _logger.LogInformation(String.Join("/r/n", result.Errors)); Console.WriteLine(String.Join("/r/n", result.Errors)); } } List<ClaimsIdentity> claimsIdentities = new List<ClaimsIdentity>(); AuthenticationProperties properties = new AuthenticationProperties() { ExpiresUtc = DateTime.UtcNow.AddMinutes(30), RedirectUri = model.ReturnUrl }; var customClaims = new List<Claim>() { new Claim("fcb", "123"), new Claim("username", "範臣斌") }; await _signInManager.SignInWithClaimsAsync(UserLoginInfo, properties, customClaims); if (string.IsNullOrEmpty(model.ReturnUrl)) { return LocalRedirect("/"); } return LocalRedirect(model.ReturnUrl); } public ActionResult FcbError() { return View(); } [HttpGet] public ActionResult FcbLoginOut() { _signInManager.SignOutAsync(); return Ok(); }
最後在需要授權的地方打上標籤就行了,流程就完了
最後再測試一下訪問有授權標籤的 /Home/Index ,會自動跳到 /Account/FcbLogin/登入頁
Perfect !!!