asp.net core2.2 用戶驗證 和受權有很詳細和特貼心的介紹,我感興趣的主要是這兩篇:微信
個人項目有兩類用戶:cookie
每類用戶中部分人員具備「Admin」角色app
由於企業微信的用戶有可能同時是微信公衆號用戶,即一我的兩個名,因此須要多用戶驗證和受權。咱用代碼說話最簡潔,以下所示:asp.net
public class DemoController : Controller { /// <summary> /// 企業微信用戶使用的模塊 /// </summary> /// <returns></returns> public IActionResult Work() { return Content(User.Identity.Name +User.IsInRole("Admin")); } /// <summary> /// 企業微信管理員使用的模塊 /// </summary> /// <returns></returns> public IActionResult WorkAdmin() { return Content(User.Identity.Name + User.IsInRole("Admin")); } /// <summary> /// 微信公衆號用戶使用的模塊 /// </summary> /// <returns></returns> public IActionResult Mp() { return Content(User.Identity.Name + User.IsInRole("Admin")); } /// <summary> /// 微信公衆號管理員使用的模塊 /// </summary> /// <returns></returns> public IActionResult MpAdmin() { return Content(User.Identity.Name + User.IsInRole("Admin")); } }
下面咱一步一步實現。async
第一步 改造類Startupide
修改ConfigureServices方法,加入如下代碼visual-studio
services.AddAuthentication ( "Work" //就是設置一個缺省的cookie驗證的名字,缺省的意思就是須要寫的時候能夠不寫。另外不少時候用CookieAuthenticationDefaults.AuthenticationScheme,這玩意就是字符串常量「Cookies」, ) .AddCookie ( "Work", //cookie驗證的名字,「Work」能夠省略,由於是缺省名 option => { option.LoginPath = new PathString("/Demo/WorkLogin"); //設置驗證的路徑 option.AccessDeniedPath= new PathString("/Demo/WorkDenied");//設置無受權訪問跳轉的路徑 }).AddCookie("Mp", option => { option.LoginPath = new PathString("/Demo/MpLogin"); option.AccessDeniedPath = new PathString("/Demo/MpDenied"); });
修改Configure方法,加入如下代碼網站
app.UseAuthentication();
第二步 添加驗證.net
public async Task WorkLogin(string returnUrl) { var claims = new List<Claim> { new Claim(ClaimTypes.Name, "UserId"), new Claim(ClaimTypes.Role, "Admin") //若是是管理員 }; var claimsIdentity = new ClaimsIdentity(claims, "Work");//「,"Work"」能夠省略,由於是缺省名 var authProperties = new AuthenticationProperties { AllowRefresh = true, //ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10), // The time at which the authentication ticket expires. A // value set here overrides the ExpireTimeSpan option of // CookieAuthenticationOptions set with AddCookie. IsPersistent = false, //持久化保存,到底什麼意思我也不太清楚,哪位兄弟清楚的話,盼解釋 //IssuedUtc = <DateTimeOffset>, // The time at which the authentication ticket was issued. RedirectUri = returnUrl ?? "/Demo/Work" }; await HttpContext.SignInAsync("Work", new ClaimsPrincipal(claimsIdentity), authProperties); } public IActionResult WorkDenied() { return Forbid(); } public async Task MpLogin(string returnUrl) { var claims = new List<Claim> { new Claim(ClaimTypes.Name, "OpenId"), new Claim(ClaimTypes.Role, "Admin") //若是是管理員 }; var claimsIdentity = new ClaimsIdentity(claims, "Mp");//「,"Mp"」不能省略,由於不是缺省名 var authProperties = new AuthenticationProperties { AllowRefresh = true, IsPersistent = false, RedirectUri = returnUrl ?? "/Demo/Mp" }; await HttpContext.SignInAsync("Mp", new ClaimsPrincipal(claimsIdentity), authProperties); } public IActionResult MpDenied() { return Forbid(); }
第三步 添加受權code
就是在對應的Action前面加[Authorize]
/// <summary> /// 企業微信用戶使用的模塊 /// </summary> /// <returns></returns> [Authorize( AuthenticationSchemes ="Work" //缺省名能夠省略 )] public IActionResult Work() { return Content(User.Identity.Name + User.IsInRole("Admin")); } /// <summary> /// 企業微信管理員使用的模塊 /// </summary> /// <returns></returns> [Authorize(AuthenticationSchemes ="Work",Roles ="Admin")] public IActionResult WorkAdmin() { return Content(User.Identity.Name + User.IsInRole("Admin")); } /// <summary> /// 微信公衆號用戶使用的模塊 /// </summary> /// <returns></returns> [Authorize(AuthenticationSchemes ="Mp")] public IActionResult Mp() { return Content(User.Identity.Name + User.IsInRole("Admin")); } /// <summary> /// 微信公衆號管理員使用的模塊 /// </summary> /// <returns></returns> [Authorize(AuthenticationSchemes ="Mp",Roles ="Admin")] public IActionResult MpAdmin() { return Content(User.Identity.Name + User.IsInRole("Admin")); }
Ctrl+F5運行,截屏以下:
最後,講講碰到的坑和求助
坑
一開始的驗證的代碼以下:
public async Task<IActionResult> Login(string returnUrl) { var claims = new List<Claim> { new Claim(ClaimTypes.Name, "UserId"), new Claim(ClaimTypes.Role, "Admin") //若是是管理員 }; var claimsIdentity = new ClaimsIdentity(claims, "Work");//「,"Work"」能夠省略,由於是缺省名 var authProperties = new AuthenticationProperties { //AllowRefresh = true, //IsPersistent = false, //RedirectUri }; await HttpContext.SignInAsync("Work", new ClaimsPrincipal(claimsIdentity), authProperties); return Content("OK"); }
運行起來之後不停的調用login,百度了半天,改了各類代碼,最後把return Content("OK");改爲return RedirectToAction("Index");一切OK!
揣摩緣由多是當 return Content("OK");時,自動調用AuthenticationProperties的RedirectUri,而RedirectUri爲空時,自動調用本身。也不知道對不對。
這時候重視起RedirectUri,原本就要返回到returnUrl,是否是給RedirectUri賦值returnUrl就能自動跳轉?
確實,return Content("OK");時候自動跳轉了,return RedirectToAction("Index");無效。
最後把Task<IActionResult> 改爲Task ,把return ...刪除,一切完美!(弱弱問一句,是否是原來就應該這樣寫?我一直在走彎路?)
求助
User有屬性Identities,看起來能夠有多個Identity,如何有?