用戶登陸是一個很是常見的應用場景 .net core 2.0 的登陸方式發生了點變化,應該是屬因而良性的變化,變得更方便,更容易擴展。後端
打開項目中的Startup.cs文件,找到ConfigureServices方法,咱們一般在這個方法裏面作依賴注入的相關配置。添加以下代碼:app
public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, o => { o.LoginPath = new PathString("/Account/Login"); o.AccessDeniedPath = new PathString("/Error/Forbidden"); }); }
這段代碼的大概意思就是,添加受權支持,並添加使用Cookie的方式,配置登陸頁面和沒有權限時的跳轉頁面。async
再找到Configure方法,添加 app.UseAuthentication(),使用受權:ide
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseAuthentication(); }
這樣基本的配置就完成了。post
添加一個Controller,如AccountController,再添加一個Action,如 Login,所配置的路由,要與上面的配置對應,否則跳轉登陸時會跳錯頁面。ui
用戶提交用戶名和密碼,登陸代碼大體以下:this
[HttpPost] public async Task <IActionResult> Login(string userName, string password, string ReturnUrl) { var user = _userService.Login(userName, password); if (user != null) { user.AuthenticationType = CookieAuthenticationDefaults.AuthenticationScheme; var identity = new ClaimsIdentity(user); identity.AddClaim(new Claim(ClaimTypes.Name, user.UserID)); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity)); if (ReturnUrl.IsNullOrEmpty()) { return RedirectToAction("Index", "Dashboard"); } return Redirect(ReturnUrl); } ViewBag.Errormessage = "登陸失敗,用戶名密碼不正確"; return View(); }
這裏要注意的是 AuthenticationType 所設置的Scheme必定要與前面的配置同樣,這樣對應的登陸受權纔會生效。url
登陸的目錄,就是但願有些頁面或者資源只有登陸之後纔可訪問。使用AuthorizeAttribute來作限制。在須要作限制的Controller上加上[Authorize]特性來作限制。.net
[Authorize] public class ThemeController { }
這樣這個Controller下的全部的Action都必須要登陸後纔可訪問。若是但願其中某些Action能夠不用登陸也可訪問,能夠添加例外:code
[AllowAnonymous] public ActionResult Index() { return View(); }
到這裏一個最基礎的登陸就完成了。
在Web項目中,一般會遇到一個問題,後端管理員和前臺用戶。這兩個用戶都是可登陸的,在 .net core 2.0,這個將很容易實現。
CookieAuthenticationDefaults.AuthenticationScheme,這是系統已經定義好的一個默認的登陸方案,添加一個新的來實現一個不一樣的身份登陸。代碼以下:
public class CustomerAuthorizeAttribute : AuthorizeAttribute { public const string CustomerAuthenticationScheme = "CustomerAuthenticationScheme"; public CustomerAuthorizeAttribute() { this.AuthenticationSchemes = CustomerAuthenticationScheme; } }
添加使用這個新的方案,在Startup.cs文件下:
public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, o => { o.LoginPath = new PathString("/Account/Login"); o.AccessDeniedPath = new PathString("/Error/Forbidden"); }) .AddCookie(CustomerAuthorizeAttribute.CustomerAuthenticationScheme, option => { option.LoginPath = new PathString("/Account/Signin"); option.AccessDeniedPath = new PathString("/Error/Forbidden"); }); }
添加新的登陸方案,並配置一個新的登陸頁面,登陸的方法和剛纔是同樣,只是AuthenticationType使用了新的方案。
[HttpPost] public async Task <IActionResult> Login(string userName, string password, string ReturnUrl) { var user = _userService.Login(userName, password); if (user != null) { user.AuthenticationType = CustomerAuthorizeAttribute.CustomerAuthenticationScheme; var identity = new ClaimsIdentity(user); identity.AddClaim(new Claim(ClaimTypes.Name, user.UserID)); await HttpContext.SignInAsync(CustomerAuthorizeAttribute.CustomerAuthenticationScheme, new ClaimsPrincipal(identity)); if (ReturnUrl.IsNullOrEmpty()) { return RedirectToAction("Index", "Dashboard"); } return Redirect(ReturnUrl); } ViewBag.Errormessage = "登陸失敗,用戶名密碼不正確"; return View(); }
使用方法和以前的差很少,換成新的CustomerAuthorizeAttribute就好了:
[CustomerAuthorize] public class CustomerController { }
CustomerAuthorizeAttribute這個類,不是必需的,只是爲了方便使用而寫,其實徹底能夠只定義一個新的方案(Scheme)就好了。
登陸了多個用戶,那麼誰纔是HttpContext.User呢?若是你的Controller或者Action上有使用AuthorizeAttribute,那這個Attribute使用的登陸方案是哪一個,則這個HttpContext.User對應的就是那個方案的登陸用戶。若是沒有使用,則AddAuthentication()方法默認指它的方案(Scheme)所登陸的用戶,就是這個HttpContext.User了。
如何獲取對應方案的登陸用戶呢?使用HttpContext.AuthenticateAsync
var auth = await HttpContext.AuthenticateAsync(CustomerAuthorizeAttribute.CustomerAuthenticationScheme); if (auth.Succeeded) { auth.Principal.Identity... }
這個就簡單了,指定方案退出就能夠了。
public async Task Logout(string returnurl) { await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); return Redirect(returnurl ?? "~/"); }