ASP.NET Core Authentication系列(二)實現(xiàn)認證、登錄和注銷
前言
在上一篇文章介紹ASP.NET Core Authentication的三個重要概念,分別是Claim, ClaimsIdentity, ClaimsPrincipal,以及claims-base authentication是怎么工作的。
這篇文章來介紹一下如何基于claims-base authentication來實現(xiàn)認證、登錄和注銷功能的。源代碼從這里下載。
認證是一個確定發(fā)送請求的訪問者身份的過程,與認證相關(guān)的還有另外兩個基本操作:登錄和注銷。
ASP.NET Core應(yīng)用的認證實現(xiàn)在一個名為AuthenticationMiddleware的中間件中,該中間件在處理分發(fā)給它的請求時會按照指定的?認證方案(Authentication Scheme)?從請求中提取能夠驗證用戶真實身份的數(shù)據(jù),我們一般將該數(shù)據(jù)稱為?安全令牌(Security Token)?。
ASP.NET Core應(yīng)用下的安全令牌被稱為?認證票據(jù)(Authentication Ticket)?,所以ASP.NET Core應(yīng)用采用基于票據(jù)的認證方式。
AuthenticationMiddleware中間件的整個認證過程涉及下圖的三種操作:認證票據(jù)的頒發(fā)、檢驗和撤銷。

ASP.NET Core應(yīng)用的認證系統(tǒng)旨在構(gòu)建一個標準的模型來完成針對請求的認證以及與之相關(guān)的登錄和注銷操作。接下來我們就通過一個簡單的實例來演示如何在一個ASP.NET Core應(yīng)用中實現(xiàn)認證、登錄和注銷的功能。
大多數(shù)Web應(yīng)用采用的是Cookie來保存認證票據(jù),因此我們采用基于Cookie的認證方案。
配置
在Startup.ConfigureServices方法里,添加AuthenticationMiddleware中間件:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
然后在Startup.Configure方法里,調(diào)用UseAuthentication和UseAuthorization來設(shè)置HttpContext.User屬性以及允許請求經(jīng)過AuthenticationMiddleware,并且要在UseEndpoints之前調(diào)用:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env){????//?...????app.UseAuthentication();????app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapControllerRoute(name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");????});????????// ...}
登錄
接下來實現(xiàn)登錄方法,常見是使用“用戶名+密碼”,這里使用一個靜態(tài)字典來模擬用戶表。
public class AccountController : Controller{????//?....????private?static?Dictionary<string,?string>?_accounts;static AccountController(){_accounts = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);_accounts.Add("Foo", "password");_accounts.Add("Bar", "password");_accounts.Add("Baz", "password");}[]public IActionResult Login(){????????LoginModel?model?=?new?LoginModel();return View(model);}[]public async Task<IActionResult> Login(LoginModel model){if (_accounts.TryGetValue(model.UserName, out var pwd) && pwd == model.Password){var claimsIdentity = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, model.UserName) }, "Basic");var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal);return Redirect("/");}else{????????????model.ErrorMessage?=?"Invalid?user?name?or?password!";return await Task.Run(() => View(model));}????}// ....}
這段代碼的關(guān)鍵在于下面三行代碼:
創(chuàng)建ClaimType為Name,值為用戶名的Claim。
創(chuàng)建ClaimsIdentity,注意AuthorizeType="Basic"。
創(chuàng)建ClaimsPrincipal。
調(diào)用HttpContext.SignInAsync登錄,其中認證方案為CookieAuthenticationDefaults.AuthenticationScheme,與配置時一致。
var claimsIdentity = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, model.UserName) }, "Basic");var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal);
認證
需要授權(quán)訪問的功能要驗證登錄狀態(tài),如果沒有登錄則不允許訪問,使用方法很簡單,只需要在Action上加上特性[Authorize]:
[]public IActionResult Index(){return View();}
未登錄會跳轉(zhuǎn)到/Account/Login(默認設(shè)置,可修改),避免未授權(quán)訪問。
注銷
用戶注釋,即將具有認證票據(jù)的Cookie設(shè)置為過期,直接調(diào)用HttpContext.SignOutAsync,注意認證方案要與配置和登錄的一致:CookieAuthenticationDefaults.AuthenticationScheme
參考資料public class AccountController : Controller{????//?....public async Task<IActionResult> Logout(){_logger.LogInformation("User {Name} logged out at {Time}.",????????????????User.Identity.Name,?DateTime.UtcNow);????????await?HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);return Redirect("/");????}????// ....}
Exploring the cookie authentication middleware in ASP.NET Core
用最簡單的方式在ASP.NET Core應(yīng)用中實現(xiàn)認證、登錄和注銷
Use cookie authentication without ASP.NET Core Identity

