here is my code and i dont know why it always executed the else statement even if i log in the user that has a role of SuperAdmin
[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);
if (User.IsInRole("SuperAdmin"))
{
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);
}
}
else
{
ModelState.AddModelError("", "you are not allowed to access this page");
//AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
return View(model);
}
}
Give me some suggestions what should i do to my code to improve it.. My issue is why my code always executing the else statement even if I use the account of SuperAdmin
Sounds like if
statement for checking current user role should be moved. Ensure if the current user successfully logged in before proceeding for user role checking, because it is possible that user still not completed all authentication process after hitting PasswordSignInAsync
method.
If you're using newer version of Identity, use UserManager.IsInRole
method instead, because User.IsInRole
uses previous version of role manager:
var user = await UserManager.FindAsync(model.Email, model.Password);
if (UserManager.IsInRole(user.Id, "SuperAdmin"))
{
// do something
}
Here is an example setup for user role checking:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
var user = await UserManager.FindAsync(model.Email, model.Password);
if (user == null)
{
// user not found or login failure, do something here
}
else
{
// proceed to role checking
var roles = await UserManager.GetRolesAsync(user.Id);
// use roles.Contains("SuperAdmin") if IsInRole still won't work
if (UserManager.IsInRole(user.Id, "SuperAdmin"))
{
return RedirectToLocal(returnUrl);
}
else
{
ModelState.AddModelError("", "you are not allowed to access this page");
return View(model);
}
}
break;
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);
}
Note: Make sure roleManager
setting in web.config has properly set and/or Roles
table has joined with Users
table in database to take effect.