ASP.NET MVC 5 Identity 2 基于用户角色的登录重定向 [英] ASP.NET MVC 5 Identity 2 Login redirect based on user role

查看:23
本文介绍了ASP.NET MVC 5 Identity 2 基于用户角色的登录重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to redirect user to page based on their role,

这是 ASP.NET MVC 5 附带的登录功能的默认实现:

This is the default implementation of the login function that come with 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");
    }
}

我希望能够根据用户的角色重定向用户,我尝试这样做:

I want to be able to redirect user based on their role, I tried to do it this way:

[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 的登录页面,这是预期的行为.

But there is a problem, although the site is redirecting me to the correct page, If i navigate by typing in the url foo.com/admin when i am not logged in with an admin account, the site brings me to the login page with url foo.com/Account/Login?ReturnUrl=%2Fadmin, which is the expected behavior.

如果我此时使用雇主帐户登录,它会将我重定向到雇主页面并以雇主身份登录我,这没有错,但事实并非如此,该网站应提及我应该使用管理员帐户登录,因为返回 url 是admin".我希望我说得有道理.

if i login with an employer account at this point, it will redirect me to the employer's page and log me in as an employer, which isn't wrong, but that shouldn't be the case, the site should mention I should login with an admin account instead because the return url is "admin". I hope i am making sense.

推荐答案

为什么在自定义重定向之前不检查是否有 returnUrl?

why dont you check if there is a returnUrl before your custom redirects?

    [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 并将您重定向回重新登录.

Like this if you navigate to foo.com/admin it will throw 401 and redirect you to login. Then if you log in as employer it will throw 401 and redirect you back to login again.

来自评论:我可以只做 Redirect(returnUrl) 并删除 RedirectToLocal 操作方法吗?"

From comments: "Can I just do Redirect(returnUrl) and delete the RedirectToLocal action method?"

RedirectToLocal(returnUrl) 方法检查是否 Url.IsLocalUrl(returnUrl).所以需要防止Open Redirect Attacks.

RedirectToLocal(returnUrl) method checks if Url.IsLocalUrl(returnUrl). So it is needed to prevent Open Redirect Attacks.

这篇关于ASP.NET MVC 5 Identity 2 基于用户角色的登录重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆