Asp.net
ASP.NET MVC 5 Identity 2 基於使用者角色的登錄重定向
我正在嘗試根據使用者的角色將使用者重定向到頁面,
這是 ASP.NET MVC 5 附帶的登錄功能的預設實現:
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (ModelState.IsValid) { var user = await UserManager.FindAsync(model.UserName, model.Password); if (user != null) { await SignInAsync(user, model.RememberMe); return RedirectToLocal(returnUrl); } else { ModelState.AddModelError("", "Invalid username or password."); } } // If we got this far, something failed, redisplay form return View(model); } private ActionResult RedirectToLocal(string returnUrl) { if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } else { return RedirectToAction("Index", "Employer"); } }我希望能夠根據使用者的角色重定向使用者,我嘗試這樣做:
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (ModelState.IsValid) { var user = await UserManager.FindAsync(model.UserName, model.Password); if (user != null) { await SignInAsync(user, model.RememberMe); //role Employer go to Employer page if (UserManager.IsInRole(user.Id, "Employer")) { return RedirectToAction("Index", "Employer"); } //role Admin go to Admin page else if (UserManager.IsInRole(user.Id, "Admin")) { return RedirectToAction("Index", "Admin"); } else { //no role return RedirectToAction("Index", "Home"); } } else { ModelState.AddModelError("", "Invalid username or password."); } } // If we got this far, something failed, redisplay form return View(model); }但是有一個問題,儘管該站點將我重定向到正確的頁面,但如果我在沒有使用管理員帳戶登錄時通過鍵入 url foo.com/admin 進行導航,該站點會將我帶到登錄頁面url foo.com/Account/Login?ReturnUrl=%2Fadmin,這是預期的行為。
如果我此時使用雇主帳戶登錄,它會將我重定向到雇首頁面並以雇主身份登錄,這沒有錯,但情況不應該如此,該網站應該提到我應該登錄一個管理員帳戶,因為返回 url 是“管理員”。我希望我說得通。
為什麼不在自定義重定向之前檢查是否有 returnUrl?
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (ModelState.IsValid) { var user = await UserManager.FindAsync(model.UserName, model.Password); if (user != null) { await SignInAsync(user, model.RememberMe); if (String.IsNullOrEmpty(returnUrl)) { if (UserManager.IsInRole(user.Id, "Employer")) { return RedirectToAction("Index", "Employer"); } //role Admin go to Admin page if (UserManager.IsInRole(user.Id, "Admin")) { return RedirectToAction("Index", "Admin"); } } else { return RedirectToLocal(returnUrl); } } else { ModelState.AddModelError("", "Invalid username or password."); } } // If we got this far, something failed, redisplay form return View(model); }像這樣,如果您導航到 foo.com/admin,它將拋出 401 並將您重定向到登錄。然後,如果您以雇主身份登錄,它將拋出 401 並將您重定向回再次登錄。
來自評論: “我可以只做 Redirect(returnUrl) 並刪除 RedirectToLocal 操作方法嗎?”
RedirectToLocal(returnUrl)方法檢查是否Url.IsLocalUrl(returnUrl). 因此需要防止開放重定向攻擊。