I have the following code I've typed into the Account Controller in my MVC project and I am in both the administrator and manager roles. When I log in I get redirected back to my home index instead of being redirected to my AdminApp index. Any ideas where I'm going wrong in my code?
[AcceptVerbs(HttpVerbs.Post)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
Justification = "Needs to take same parameter type as Controller.Redirect()")]
public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl)
{
if (!ValidateLogOn(userName, password))
{
return View();
}
FormsAuth.SignIn(userName, rememberMe);
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
if (User.IsInRole("Administrator") || (User.IsInRole("Manager")))
{
return RedirectToAction("Index", "AdminApp");
}
else
{
return RedirectToAction("Index", "Home");
}
}
}
I'm using VS 2013 and it's new Identity model, I ended up going with this:
You need to un-nest the if statement. Revise as follows:
Change this:
to this:
The problem is the the line
if(!String.IsNullOrEmpty(returnUrl)))
is evaluating to True because the returnUrl parameter has the url of the page you came from by default.The reason your code is not working as expected is because the
User
has technically not been signed in and authenticated yet. Say what? But you did call SignIn!FormsAuth.SignIn(userName, rememberMe);
- which in this case is just a wrapper forFormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
- only sets the asp.net authorization cookie on the users browser as part of the response. It is only for requests after this point that the user's browser will have the cookie, causing the asp.net membership to properly set up the 'User' object. All of your code in the LogOn method is still assuming an anonymous user, so your IsInRole check fails and you are redirected home. Put your if statement on another page and after you've signed in, you'll see that nowUser.IsInRole
works as expected. (And indeed, this is what you'd use User.IsInRole for, just not during the logon process)So how to check during the actual logon process?
Roles.IsUserInRole
orRoles.GetRolesForUser
are a couple of ways, eg.:You must explicitly specify the user name of the user logging in, which will actually execute a query against the membership datastore. On that note, I believe the above code would as a result cause two queries to be executed, which you may find less than ideal. This is where Roles.GetRolesForUser might be a better option:
Hope that helps!