2009-12-08 4 views
7

Ich habe den folgenden Code, den ich in meinem MVC-Projekt in den Account Controller eingegeben habe und ich bin sowohl in der Administrator-und Manager-Rollen. Wenn ich mich anmelde, werde ich zurück zu meinem Heim-Index weitergeleitet, anstatt zu meinem AdminApp-Index umgeleitet zu werden. Irgendwelche Ideen, wo ich in meinem Code falsch liege?Wie kann ich die ASP.Net MVC Login Redirect basierend auf der Rolle ändern?

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

     } 
    } 

Antwort

19

Der Grund, warum Ihr Code nicht wie erwartet funktioniert, ist, dass die User technisch nicht angemeldet und authentifiziert worden ist. Sag was? Aber du hast SignIn angerufen!

FormsAuth.SignIn(userName, rememberMe); - die in diesem Fall nur ein Wrapper für FormsAuthentication.SetAuthCookie(userName, createPersistentCookie); ist - setzt nur den asp.net-Berechtigungscookie im Browser des Benutzers als Teil der Antwort. Es ist nur für Anfragen nach diesem Punkt, dass der Browser des Benutzers den Cookie haben wird, wodurch die asp.net Mitgliedschaft ordnungsgemäß das "Benutzer" -Objekt einrichten. Der gesamte Code in der LogOn-Methode geht weiterhin von einem anonymen Benutzer aus, sodass Ihre IsInRole-Prüfung fehlschlägt und Sie nach Hause weitergeleitet werden. Setzen Sie Ihre if-Anweisung auf eine andere Seite und nachdem Sie sich angemeldet haben, sehen Sie, dass User.IsInRole nun wie erwartet funktioniert. (Und in der Tat, das ist, was Sie User.IsInRole für verwenden würden, nur nicht während des Anmeldevorgangs)

So, wie während des eigentlichen Anmeldevorgangs zu überprüfen? Roles.IsUserInRole oder Roles.GetRolesForUser sind ein paar Möglichkeiten, wie zB .:

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

Sie explizit den Benutzernamen des Benutzers der Anmeldung angeben müssen, die eine Abfrage für die Mitgliedschaft Datenspeicher tatsächlich ausgeführt wird. In diesem Sinne glaube ich, dass der obige Code dazu führen würde, dass zwei Abfragen ausgeführt werden, die Sie möglicherweise als nicht ideal empfinden. Dies ist, wo Roles.GetRolesForUser eine bessere Option sein könnte:

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

Hoffe, dass hilft!

+0

arbeitete wie ein Charme! Ich schätze die Hilfe! – Ben

+0

Es ist 3 1/2 Jahre später aber jetzt .. danke! – peter

+0

Wow! Es funktioniert immer noch für ** Asp.Net Core **. – vivek

0

Sie müssen die if-Anweisung aufheben. Revidieren wie folgt:

ändern diese:

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

dazu:

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

Das Problem ist, die die Linie if(!String.IsNullOrEmpty(returnUrl))) auf True auswertet, weil der returnUrl Parameter die URL der Seite hat man kam standardmäßig.

+0

hmm. Ich habe es versucht und nicht für mich gearbeitet. Ich kann die User.InInRole erfolgreich auf einer Aspx-Seite verwenden, um Links anzuzeigen/zu verbergen, aber es funktioniert nicht, wenn ich es in einem Controller habe. Gibt es eine andere Möglichkeit, dies in der Steuerung durchzuführen? – Ben

+0

Sollte nicht viel Unterschied machen, aber Sie können Roles.IsUserInRole() versuchen. Ich denke jedoch, dass dies die gleiche Methode ist, die am Ende von der User.IsInRole() -Methode aufgerufen wird. –

2

Ich bin mit VS 2013 und es ist neue Identität Modell, landete ich mit diesem hinauf:

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