在以前的Asp.Net中可以用 FormsAuthentication 類的一系列方法來使用加密的Cookie存儲用戶身份,使用簡單,可控性強。在Asp.Net Core中是否也可以的?答案是當然的。
使用步驟:
1、在 project.json 中添加項目依賴 "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0":
"dependencies": { "Microsoft.NETCore.App": { "version": "1.0.1", "type": "platform" }, "Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Mvc": "1.0.1", "Microsoft.AspNetCore.Razor.Tools": { "version": "1.0.0-preview2-final", "type": "build" }, "Microsoft.AspNetCore.Routing": "1.0.1", "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", "Microsoft.AspNetCore.Server.Kestrel": "1.0.1", "Microsoft.AspNetCore.StaticFiles": "1.0.0", "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.0.0", "Microsoft.Extensions.Logging": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Extensions.Logging.Debug": "1.0.0", "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0", "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0" }
2、在 Startup.cs 中添加中間件:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseBrowserLink(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationScheme = "member", // Cookie 驗證方案名稱,后面多處都需要用到,部分地方必須要求常量,所以直接配置為字符串。 AutomaticAuthenticate = true, // 是否自動啟用驗證,如果不啟用,則即便客服端傳輸了Cookie信息,服務端也不會主動解析。
// 除了明確配置了 [Authorize(ActiveAuthenticationSchemes = "上面的方案名")] 屬性的地方,才會解析,此功能一般用在需要在同一應用中啟用多種驗證方案的時候。比如分Area. LoginPath = "/account/login" // 登錄頁 }); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
3、創建一個新的 Controller,並添加登錄的方法,大致如下:
[AllowAnonymous] public async Task<IActionResult> Login() { // 這里應該寫業務邏輯來獲取用戶名,用戶Id等信息。 var userId = 10000; var userName = "admin"; // ======================== var identity = new ClaimsIdentity("Forms"); // 指定身份認證類型 identity.AddClaim(new Claim(ClaimTypes.Sid, userId.ToString())); // 用戶Id identity.AddClaim(new Claim(ClaimTypes.Name, userName)); // 用戶名稱 var principal = new ClaimsPrincipal(identity); await HttpContext.Authentication.SignInAsync("member", principal, new AuthenticationProperties { IsPersistent = true });
string returnUrl = Request.Query["returnUrl"];
if (!string.IsNullOrEmpty(returnUrl)) return Redirect(returnUrl);
return RedirectToAction("index", "account");
}
4、退出登錄方法:
public async Task<IActionResult> Logout() { await HttpContext.Authentication.SignOutAsync("member"); // Startup.cs中配置的驗證方案名
return RedirectToAction("index", "home");
}
5、獲取用戶信息:
[Authorize(ActiveAuthenticationSchemes = "member")] public IActionResult Index() { var userId = User.FindFirst(ClaimTypes.Sid).Value; var userName = User.Identity.Name; return Json(new { Id = userId, Name = userName }); }
其它說明:
這里生成的Cookie是加密過的,大概如下:
相關的Cookie名稱,域,過期時間等都可以在 Startup.cs 中進行設置,大概如下:
app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationScheme = "member", // 驗證方案名 AutomaticAuthenticate = true, // 是否自動啟用驗證 LoginPath = "/account/login", // 登錄地址 CookieDomain = "abc.com", // 驗證域 CookieName = "abc", // Cookie 名稱 CookiePath = "/", // Cookie 路徑 ExpireTimeSpan = TimeSpan.FromDays(3), // 過期時間 SlidingExpiration = true, // 是否在過期時間過半的時候,自動延期 CookieHttpOnly = true // 是否允許客戶端Js獲取。默認True,不允許。 });
步驟很簡單,也是極好用的,若結合是否自動啟用驗證的AutomaticAuthenticate來進行Area分區域認證,靈活性更強。