How to redirect user to page after login?

4

I'm developing a web application, using Asp.Net MVC 5 com Identity and I'm using Roles to perform the authorization.

I am trying to do that depending on the Role that the user has, it is directed to a different "Home" page.

Example:

  • Administrators = > Home of the Administration;
  • Sellers = > Home of the Commercial.

And so it goes. But I'm having a hard time finding a solution.

To redirect the user when I have access denied by Roles , I sub-wrote the HandleUnauthorizedRequest method:

  protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            // The user is not authenticated
            base.HandleUnauthorizedRequest(filterContext);
        }
        else if (!this.Roles.Split(',').Any(filterContext.HttpContext.User.IsInRole))
        {
            // The user is not in any of the listed roles => 
            // show the unauthorized view
            filterContext.Result = new ViewResult
            {
                ViewName = "~/Views/Shared/Page_403.cshtml"
            };
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }

Now, to perform this redirect, after logging in? How would you do?

Controller code Account :

        //
        // POST: /Account/Login
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        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:
                    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);
            }
        }

When attempting to validate using the condition: if(UserManager.IsInRole(User.Identity.GetUserId(), "admin")) the error was generated:

CodeofHomeController:

publicclassHomeController:Controller{[PermissoesFiltro]publicActionResultIndex(){returnView();}[PermissoesFiltro(Roles="Comercial")]
    public ActionResult Index_Comercial()
    {
        return View();
    }

    [PermissoesFiltro(Roles = "Master")]
    public ActionResult Index_Master()
    {
        return View();
    }

Identity Tables:

    
asked by anonymous 31.10.2016 / 11:05

2 answers

6

There is a controller property called User , as soon as the login is successful this property will have a value (identity information This is not quite true, see update just below;

This property will be "powered" by Identity and must implement the IPrincipal interface. In this interface, there is the IsInRole(string role) method which is exactly what you need.

I'm going to focus on the part of the code that really matters, what's going to be done in there depends on what's really needed for your project, you can ask the bank to retrieve the URL, you can do more validations. The important thing is to understand that User.IsInRole is exactly what you need.

case SignInStatus.Success:
    {       
        if(User.IsInRole("Admin")) // Se o usuário estiver na role admin
            return RedirectToLocal("UrlAdmin"); //Redireciona para uma URL pré-definida

        return RedirectToLocal(returnUrl);  
    }

Update

In fact, the User property is still empty at login time, so you will need another strategy to recover the user that is currently logged in.

var user = await UserManager.FindAsync(model.Email, model.Password); 

if (UserManager.IsInRole(user.Id, "Admin"))
    return RedirectToAction("Home_Admin", "Controller"); //A forma de redirect que irá usar

UserManager is a property of AccountController .

    
31.10.2016 / 12:32
2

You can try to override the OnAuthorization authorization method by passing the route values, by default they are three route values: controller , action and area , the latter if there is an area. Since you have already overwritten the HandleUnauthorizedRequest method, it is also okay to override the authorization, leaving the redirects handling in the same place.

 public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var dicRota = new Dictionary<string, object>();

        if (filterContext.HttpContext.User.IsInRole("Admin"))
        {
            dicRota.Add("controller", "Admin");
            dicRota.Add("action", "Home");
        }
        else if (filterContext.HttpContext.User.IsInRole("Vendedores"))
        {
            dicRota.Add("controller", "Comercial");
            dicRota.Add("action", "Home");
        }

        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(dicRota));
    }
    
31.10.2016 / 13:21