Asp .Net Core 2.0 登錄授權以及多用戶登錄
用戶登錄是一個非常常見的應用場景 .net core 2.0 的登錄方式發生了點變化,應該是屬於是良性的變化,變得更方便,更容易擴展。
配置
打開項目中的Startup.cs文件,找到ConfigureServices方法,我們通常在這個方法裏面做依賴註入的相關配置。添加如下代碼:
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的方式,配置登錄頁面和沒有權限時的跳轉頁面。
再找到Configure方法,添加 app.UseAuthentication(),使用授權:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseAuthentication(); }
這樣基本的配置就完成了。
登錄
添加一個Controller,如AccountController,再添加一個Action,如 Login,所配置的路由,要與上面的配置對應,不然跳轉登錄時會跳錯頁面。
用戶提交用戶名和密碼,登錄代碼大致如下:
[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一定要與前面的配置一樣,這樣對應的登錄授權才會生效。
使用登錄身份
登錄的目錄,就是希望有些頁面或者資源只有登錄以後才可訪問。使用AuthorizeAttribute來做限制。在需要做限制的Controller上加上[Authorize]特性來做限制。
[Authorize] public class ThemeController { }
這樣這個Controller下的所有的Action都必需要登錄後才可訪問。如果希望其中某些Action可以不用登錄也可訪問,可以添加例外:
[AllowAnonymous] public ActionResult Index() { return View(); }
到這裏一個最基礎的登錄就完成了。
在Web項目中,通常會遇到一個問題,後端管理員和前臺用戶。這兩個用戶都是可登錄的,在 .net core 2.0,這個將很容易實現。
多用戶登錄
添加一個登錄方案(Scheme)
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?
登錄了多個用戶,那麽誰才是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 ?? "~/"); }
原文地址:http://www.zkea.net/codesnippet/detail/post-60
Asp .Net Core 2.0 登錄授權以及多用戶登錄