ASP.NET MVC 5 Identity 2 Login redirect based on user role

Mindless

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

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);
}

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.

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.

tmg

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);
   }

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.

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

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

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Asp.net Identity 2.0 - redirect externally authenticated user based on role at login

laravel 5 redirect user after login based on user's role

ASP.NET MVC5 Identity issue with User.Identity.GetUserId() during login process

Asp.net MVC 5, Identity 2.0 Unable to add a Role to user

How to create new user accounts from another (admin role) account in ASP.NET MVC 5 (Identity)

ASP.NET MVC 5 Identity 2.0, Windows Auth, User model with role attribute

ASP.NET Login Redirect Loop when user not in role

Checking if a user is in a role in asp.net mvc Identity

How to change user login credentials in identity asp.net mvc?

Login popup with Identity framework in ASP.NET MVC 5

ASP.Net MVC5: How to redirect and show right error message when user does not have a specific role for action

Get Logged in User Role: Asp.net MVC5

Removing a user from a role in ASP.NET MVC 5

ASP.Net MVC 5 Check User Role For _Layout

Asp.net MVC 5 redirect to Account/Login

Role based tokens ASP.net Identity

ASP.NET MVC 5 - Default Identity user CRUD

After Login User redirect different Page according to Role In asp.net

Asp.net Identity (MVC 5) cross subdomain login and application pool identity

Redirection to User Profile After Login in ASP.NET MVC 5

Disable Input Fields in MVC View on Role Based Authorization using ASP.net Identity

Adding [Authorize] to controller failing to redirect to Identity Login route. ASP.NET CORE 3.1 MVC

Asp.net core role based access identity / roles make user table self referencing

How do you completely hide an element from a user based on their ASP.NET Identity Role?

ASP.Net MVC Alternative Login to identity

User-role based login always redirect to the same page

How to invalidate .AspNet.ApplicationCookie after Adding user to Role using Asp.Net Identity 2?

Where is the appropriate spot to seed and login a default user with ASP.NET MVC Identity 2.0?

Add a Custom property to ASP.NET MVC Identity after user login