2009-12-08 16 views
7

Tengo el siguiente código que he tipeado en el controlador de cuenta en mi proyecto MVC y estoy en las funciones de administrador y gerente. Cuando inicio sesión, me redirigen al índice de mi casa en lugar de ser redirigido a mi índice AdminApp. ¿Alguna idea de dónde me estoy equivocando en mi código?¿Cómo puedo cambiar el redireccionamiento de inicio de sesión MVC de ASP.Net basado en el rol?

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

     } 
    } 

Respuesta

19

La razón por la que su código no funciona como se esperaba es porque el User tiene técnicamente no sido firmado y autenticado todavía. ¿Que qué? ¡Pero sí llamaste a SignIn!

FormsAuth.SignIn(userName, rememberMe); - que en este caso es solo un contenedor para FormsAuthentication.SetAuthCookie(userName, createPersistentCookie); - solo establece la cookie de autorización asp.net en el navegador de los usuarios como parte de la respuesta. Es solo para solicitudes después de este punto que el navegador del usuario tendrá la cookie, haciendo que la membresía asp.net configure correctamente el objeto 'Usuario'. Todo su código en el método LogOn sigue suponiendo que es un usuario anónimo, por lo que su comprobación IsInRole falla y se le redirige a su casa. Ponga su declaración if en otra página y después de que haya iniciado sesión, verá que ahora User.IsInRole funciona como se esperaba. (Y de hecho, esto es para lo que utilizaría User.IsInRole, solo que no durante el proceso de inicio de sesión)

Entonces, ¿cómo verificar durante el proceso de inicio de sesión real? Roles.IsUserInRole o Roles.GetRolesForUser son un par de maneras, por ejemplo .:

if (Roles.IsUserInRole(userName, "Administrator") || Roles.IsUserInRole(userName, "Administrator")) 
{ 
    return RedirectToAction("Index", "AdminApp"); 
} 

Debe especificar explícitamente el nombre de usuario del usuario en el registro, que en realidad va a ejecutar una consulta en el almacén de datos de miembros. En ese sentido, creo que el código anterior provocará la ejecución de dos consultas, que puede encontrar menos que ideales. Aquí es donde Roles.GetRolesForUser podría ser una mejor opción:

string[] roles = Roles.GetRolesForUser(userName); 
if (roles.Contains("Administrator") || roles.Contains("Manager")) 
{ 
    return RedirectToAction("Index", "AdminApp"); 
} 

Espero que ayude!

+0

funcionó como un encanto! Aprecio la ayuda! – Ben

+0

Ahora son 3 1/2 años pero ... ¡gracias! – peter

+0

¡Guau! Todavía funciona igual para ** Asp.Net Core **. – vivek

0

Necesita anular la anotación if. Revisar la siguiente manera:

cambiar esta situación:

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

a esto:

if (User.IsInRole("Administrator") || (User.IsInRole("Manager"))) 
{    
    return RedirectToAction("Index", "AdminApp");  
} 
else   
{     
return RedirectToAction("Index", "Home"); 
}  

El problema es el de la línea if(!String.IsNullOrEmpty(returnUrl))) está evaluando a cierto porque el parámetro ReturnURL tiene la url de la página vino de forma predeterminada.

+0

hmm. Lo intenté y no funcionó para mí. Puedo usar el User.InInRole con éxito en una página aspx para mostrar/ocultar enlaces, pero no funciona cuando lo tengo en un controlador. ¿Hay alguna otra forma de realizar esto en el controlador? – Ben

+0

No debería hacer mucha diferencia, pero puede probar Roles.IsUserInRole(). Sin embargo, creo que este es el mismo método que termina siendo llamado por el método User.IsInRole(). –

2

estoy usando VS 2013 y que el modelo nuevo de identidad, terminé yendo con esto:

foreach (IdentityUserRole identityUserRole in user.Roles) 
{ 
    if (identityUserRole.RoleId == "AdminRoleId") 
    { 
    return RedirectToAction("Index", "Admin"); 
    } 
    else if (identityUserRole.RoleId == "MemberRoleId") 
    { 
    return RedirectToAction("Index", "Members"); 
    } 
} 
Cuestiones relacionadas