Search code examples
asp.netasp.net-mvcasp.net-identityidentityasp.net-identity-2

find user role in identity asp mvc


I am using this code for login. How can I find a user role when user login?

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {

        if (!ModelState.IsValid)
        {
            return View(model);
        }
        var user = await UserManager.FindByNameAsync(model.Username);
        if (user != null)
        {
            if (!await UserManager.IsEmailConfirmedAsync(user.Id))
            {
                ViewBag.errorMessage = "You must have a confirmed email to log on.";
                return View("Error");
            }
        }
        var result = await SignInManager.PasswordSignInAsync(model.Username, 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);
        }
    }

Solution

  • user.Roles will fetch list of Roles user belong to. Based on your requirement you can do something like below

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
    
        if (!ModelState.IsValid)
        {
            return View(model);
        }
        var user = await UserManager.FindByNameAsync(model.Username);
        if (user != null)
        {
            if (!await UserManager.IsEmailConfirmedAsync(user.Id))
            {
                ViewBag.errorMessage = "You must have a confirmed email to log on.";
                return View("Error");
            }
        }
        var result = await SignInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberMe, shouldLockout: false);
        switch (result)
        {
            case SignInStatus.Success:
                if(await UserManager.IsInRoleAsync(user.Id,"Admin")) //<= Checking Role and redirecting accordingly.
                    return RedirectToAction("Index", "Admin");
                else
                    return RedirectToAction("Index", "User");
            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);
        }
    }
    

    Based on our discussion if you want to fetch all the roles from database you need to do below

    Add ApplicationRoleManager class to your IdentityConfig.cs as below

    public class ApplicationRoleManager : RoleManager<IdentityRole>
    {
        public ApplicationRoleManager(IRoleStore<IdentityRole, string> store)
            : base(store)
        {
        }
    
        public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
        {
            var manager = new ApplicationRoleManager(new RoleStore<IdentityRole>(context.Get<ApplicationDbContext>()));
            return manager;
        } 
    }
    

    Assign RoleManager to Owin Context, so add below to starup.auth.cs

    public void ConfigureAuth(IAppBuilder app)
        {
         // Configure the db context, user manager and signin manager to use a single instance per request
            app.CreatePerOwinContext(ApplicationDbContext.Create);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
            app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
            app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
            //other code here
    }
    

    In AccountController.cs add a property

        private ApplicationRoleManager _roleManager;
    
        public ApplicationRoleManager RoleManager
        {
            get
            {
                return _roleManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationRoleManager>();
            }
            private set
            {
                _roleManager = value;
            }
        }
    

    Pass it in the Constructor

        public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager,ApplicationRoleManager roleManager )
        {
            UserManager = userManager;
            SignInManager = signInManager;
            RoleManager = roleManager;
        }
    

    Once you are done with this you can fetch list of all roles by using var roles = RoleManager.Roles;

    You can use this as per your requirement.