ASP.NET MVC 5 Identity 2 基于用户角色的登录重定向

标签 asp.net asp.net-mvc redirect controller asp.net-identity

我正在尝试根据用户的角色将用户重定向到页面,

这是 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,这是预期的行为。

如果我此时使用雇主帐户登录,它会将我重定向到雇主页面并以雇主身份登录,这并没有错,但情况不应该如此,该网站应该提到我应该使用管理员帐户登录,因为返回网址是“admin”。我希望我说得有道理。

最佳答案

为什么不在自定义重定向之前检查是否有 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)。因此需要防止开放重定向攻击。

关于ASP.NET MVC 5 Identity 2 基于用户角色的登录重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26526536/

相关文章:

ASP.NET自定义控件,模板字段可以有属性吗?

asp.net-mvc - 发布到服务器时 MVC ActionLinks 呈现为空

.net - 如何在ASP.NET MVC中更改默认 View 位置方案?

.htaccess - 从非 www 重定向到 www 并强制使用 SSL

ruby-on-rails - 使用 Devise 4 登录后重定向

asp.net - ViewBag为什么叫ViewBag?

c# - 在 Asp.net session 中存储大量数据

asp.net - 如何在linux上启动asp.net core服务器并保持运行

c# - ASP.NET MVC5 删除 API 错误的 html 响应

c# - 通过重定向进行基本身份验证