基于角色的ASP.NET MVC登录和重定向

5
我正在使用由ASP.NET MVC生成的默认登录方法,并希望更改它,使其基于用户角色重定向到指定的视图。我已经检查了该用户是否属于该角色。我在SignInStatus成功块中进行了重定向,但没有成功。
我在其他代码块中使用User.IsInRole(),并且工作正常。我认为当执行if语句时,用户没有完全登录。我认为这是问题所在,但我不确定可以实现什么解决方法。
以下是我的代码。
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateCustomAntiForgeryTokenAttribute]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    // This doesn't count login failures towards account lockout
    // To enable password failures to trigger account lockout, change to shouldLockout: true
    var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
    switch (result)
    {
        case SignInStatus.Success:
            if (User.IsInRole("Customer"))
            {
                return RedirectToAction("Customer", "Home");
            }
            else if (User.IsInRole("Requestor"))
            {
                return RedirectToAction("Caterer", "Home");
            }
            else if (User.IsInRole("Admin"))
            {
                return RedirectToAction("Admin", "Home");
            }
            else
            {
                return RedirectToLocal(returnUrl);
            }
        case SignInStatus.LockedOut:
            return View("Lockout");
        case SignInStatus.RequiresVerification:
            return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
        case SignInStatus.Failure:
        default:
            ModelState.AddModelError("", "Invalid login attempt.");
            return View(model);
    }
}

1
可能相关:http://stackoverflow.com/questions/26273598/why-does-isinrole-always-return-false - stephen.vakil
4个回答

4
感谢@stephen.vakil提供的链接,我成功地通过更改SignInStatus.Success案例内的代码块使其正常工作。
            case SignInStatus.Success:
                var user = await UserManager.FindAsync(model.Email, model.Password);
                var roles = await UserManager.GetRolesAsync(user.Id);

                if (roles.Contains("Customer"))
                {
                    return RedirectToAction("Customer", "Home");
                }
                else if (roles.Contains("Requestor"))
                {
                    return RedirectToAction("Caterer", "Home");
                }
                else if (roles.Contains("Admin"))
                {
                    return RedirectToAction("Admin", "Home");
                }
                else
                {
                    return RedirectToLocal(returnUrl);
                }
                ......

1
[HttpPost]
public async Task<IActionResult> SignIn([FromForm]LoginDto userDto, string returnUrl)
{
    if (ModelState.IsValid)
    {
        //var googlereCaptcha = _googlereCaptchaService.ResponceVerify(userDto.ReCaptchaToken);
        //if (!googlereCaptcha.Result.success && googlereCaptcha.Result.score <= 0.5)
        //{
        //    TempData["LoginSuccessMsg"] = "You are not Human.";
        //    return await Task.Run(() => View("SignIn"));
        //}

        var signedUser = await userManager.FindByEmailAsync(userDto.Email);
        var result = await signInManager.PasswordSignInAsync(signedUser.Email, userDto.Password, userDto.RememberMe, lockoutOnFailure: false);

        if (result.Succeeded)
        {
            if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
            {
                return LocalRedirect(returnUrl);
            }
            else
            {
                var roles = await userManager.GetRolesAsync(signedUser);
                if (roles.Contains("Super Admin"))
                    return RedirectToAction("Dashboard", "User");
                if (roles.Contains("Data Entry Operator"))
                    return RedirectToAction("BusinessList", "Business");
                if (roles.Contains("Business Admin"))
                    return RedirectToAction("MyBusiness", "Business");
            }
        }

        ModelState.AddModelError(string.Empty, "Invalid Login Attempt");
    }

    return await Task.Run(() => View(userDto));
}

1

你是正确的。在这里引用的User对象是由ASP.NET管道中的“身份验证”步骤设置的。有关此信息的更多信息,请查看ASP.NET 5应用程序的生命周期

PasswordSignInAsync仅验证用户并为未来的请求设置身份验证cookie。它不会影响User对象,后者仍将表示通过管道传递的未经身份验证的状态。

实现你想要的简单方法是让你的登录方法重定向到另一个操作(例如RedirectUser),然后执行基于角色的路由。该方法将完全访问已认证的User对象和IsInRole方法。

或者,您可以实现自己的User.IsInRole方法,直接查询您的数据库。


0
如果您想使用 ASP.NET Identity 的默认登录方式,那么在成功登录后,您应该像这样获取角色,然后进行重定向以解决此问题。
       var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
        switch (result)
        {
            case SignInStatus.Success:

                var userId = SignInManager.AuthenticationManager.AuthenticationResponseGrant.Identity.GetUserId();
                if (UserManager.IsInRole(userId, "Super Admin"))
                {
                    return RedirectToAction("Index", "DashBoard");
                }}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接