(使用ASP.NET 4.X 中的時候必定都用過Forms認證即FormsAuthentication作登陸用戶的身份認證,FormsAuthentication的核心就是Cookie,ASP.NET會將用戶名存儲在Cookie中。可是它很難進行擴展,更沒法與第三方認證集成,所以,在 ASP.NET Core 中對認證與受權進行了全新的設計,並使用基於聲明的認證(claims-based authentication))數組
@{ ViewData["Title"] = "Admin"; } <h2>@ViewData["Title"]</h2> <p>Admin Page</p>
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options=>{//自定義登錄地址,不配置的話則默認爲http://localhost:5000/Account/Login options.LoginPath="/Account/MyLogin"; });
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseCookiePolicy(); //注意app.UseAuthentication方法必定要放在下面的app.UseMvc方法前面,否者後面就算調用HttpContext.SignInAsync進行用戶登陸後,使用 //HttpContext.User仍是會顯示用戶沒有登陸,而且HttpContext.User.Claims讀取不到登陸用戶的任何信息。 //這說明Asp.Net OWIN框架中MiddleWare的調用順序會對系統功能產生很大的影響,各個MiddleWare的調用順序必定不能反 app.UseAuthentication(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
這裏順便說一下app.UseAuthentication是用來幹什麼的,app.UseAuthentication會啓用Authentication中間件,該中間件會根據當前Http請求中的Cookie信息來設置HttpContext.User屬性(後面會用到),因此只有在app.UseAuthentication方法以後註冊的中間件纔可以從HttpContext.User中讀取到值,這也是爲何上面強調app.UseAuthentication方法必定要放在下面的app.UseMvc方法前面,由於只有這樣ASP.NET Core的MVC中間件中才能讀取到HttpContext.User的值。瀏覽器
public class AccountController : Controller { public IActionResult Index() { return View(); } //登錄 public IActionResult MakeLogin() { var claims = new List<Claim>(){ new Claim(ClaimTypes.Name,"wangyuting"), new Claim(ClaimTypes.Role,"admin") }; //必需要加CookieAuthenticationDefaults.AuthenticationScheme,否則沒法解析 var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity)); return Ok(); } //登出 public IActionResult Logout() { HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); return Ok(); } }
在ASP.NET CORE中使用Cookie認證登陸用戶的方法和傳統的FormsAuthentication不太同樣,大體步驟以下:cookie
因此咱們能夠看到整個ASP.NET CORE的Cookie認證登陸流程比之前ASP.NET的FormsAuthentication仍是要複雜許多,畢竟之前一個FormsAuthentication.SetAuthCookie方法就搞定了。app
在本文的例子中咱們在項目中默認的HomeController中建立了一個Acion方法Login,來實現用戶登陸的代碼。固然這裏咱們實現的是最簡的Cookie登陸,下面代碼中實際上還能夠設置Cookie是否持久化、Cookie多久過時、存儲登陸用戶信息的Cookie的名字是什麼等,咱們就不作過多介紹了,你們能夠閱讀本文最後推薦的兩份官方文檔瞭解更多。框架
/// <summary> /// 該Action登陸用戶Wangdacui到Asp.Net Core /// </summary> public IActionResult Login() { //下面的變量claims是Claim類型的數組,Claim是string類型的鍵值對,因此claims數組中能夠存儲任意個和用戶有關的信息, //不過要注意這些信息都是加密後存儲在客戶端瀏覽器cookie中的,因此最好不要存儲太多特別敏感的信息,這裏咱們只存儲了用戶名到claims數組, //表示當前登陸的用戶是誰 var claims = new[] { new Claim("UserName", "Wangdacui") }; var claimsIdentity = new ClaimsIdentity( claims, CookieAuthenticationDefaults.AuthenticationScheme); ClaimsPrincipal user = new ClaimsPrincipal(claimsIdentity); Task.Run(async () => { //登陸用戶,至關於ASP.NET中的FormsAuthentication.SetAuthCookie await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user); //可使用HttpContext.SignInAsync方法的重載來定義持久化cookie存儲用戶認證信息,例以下面的代碼就定義了用戶登陸後60分鐘內cookie都會保留在客戶端計算機硬盤上, //即使用戶關閉了瀏覽器,60分鐘內再次訪問站點仍然是處於登陸狀態,除非調用Logout方法註銷登陸。 //注意其中的AllowRefresh屬性,若是AllowRefresh爲true,表示若是用戶登陸後在超過50%的ExpiresUtc時間間隔內又訪問了站點,就延長用戶的登陸時間(其實就是延長cookie在客戶端計算機硬盤上的保留時間), //例如本例中咱們下面設置了ExpiresUtc屬性爲60分鐘後,那麼當用戶登陸後在大於30分鐘且小於60分鐘內訪問了站點,那麼就將用戶登陸狀態再延長到當前時間後的60分鐘。可是用戶在登陸後的30分鐘內訪問站點是不會延長登陸時間的, //由於ASP.NET Core有個硬性要求,是用戶在超過50%的ExpiresUtc時間間隔內又訪問了站點,才延長用戶的登陸時間。 //若是AllowRefresh爲false,表示用戶登陸後60分鐘內無論有沒有訪問站點,只要60分鐘到了,立馬就處於非登陸狀態(不延長cookie在客戶端計算機硬盤上的保留時間,60分鐘到了客戶端計算機就自動刪除cookie) /* await HttpContext.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, user, new AuthenticationProperties() { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(60), AllowRefresh = true }); */ }).Wait(); return View(); }
若是當前Http請求原本登陸了用戶A,如今調用HttpContext.SignInAsync方法登陸用戶B,那麼至關於註銷用戶A,登陸用戶Basync
3.讀取登陸用戶信息ui
那麼用戶登陸後怎麼將登陸用戶的信息(好比用戶名)讀取出來呢?咱們在HomeController的Index方法中演示瞭如何判斷當前用戶是否已經登陸,而且讀出登陸用戶的用戶名,Index方法的代碼以下所示:加密
/// <summary> /// 該Action判斷用戶是否已經登陸,若是已經登陸,那麼讀取登陸用戶的用戶名 /// </summary> public IActionResult Index() { //若是HttpContext.User.Identity.IsAuthenticated爲true, //或者HttpContext.User.Claims.Count()大於0表示用戶已經登陸 if (HttpContext.User.Identity.IsAuthenticated) { //這裏經過 HttpContext.User.Claims 能夠將咱們在Login這個Action中存儲到cookie中的全部 //claims鍵值對都讀出來,好比咱們剛纔定義的UserName的值Wangdacui就在這裏讀取出來了 var userName = HttpContext.User.Claims.First().Value; } return View(); }
注意,最好仍是用HttpContext.User.Identity.IsAuthenticated來判斷用戶是否已經登陸spa
註銷用戶設計
那麼登陸用戶後怎麼註銷登陸呢?咱們在HomeController的Logout方法中演示瞭如何註銷登陸的用戶,代碼以下所示:
/// <summary> /// 該Action從Asp.Net Core中註銷登陸的用戶 /// </summary> public IActionResult Logout() { Task.Run(async () => { //註銷登陸的用戶,至關於ASP.NET中的FormsAuthentication.SignOut await HttpContext.SignOutAsync(); }).Wait(); return View(); }
果當前Http請求原本就沒有登陸用戶,那麼調用HttpContext.SignOutAsync方法時也不會報錯