2010-11-02 16 views
10

Wenn ich die RoleProvider-Klasse implementieren und Roles.IsUserInRole (Zeichenfolge-Benutzername, Zeichenfolge-Rolle-Name) aufrufen, geht Codeausführung zuerst zu der Methode 'GetRolesForUser (Zeichenfolge-Benutzername)'. Warum ist das? Ich möchte nicht alle Rollen iterieren, wenn ich nur nach dem einzelnen Wert suche, ob dieser Benutzer in eine Rolle gehört. Ist das eine Einschränkung der .NET-Rollenanbieter-Klasse oder gibt es etwas, was ich tun kann, um die Ausführung von Code ein wenig mehr zu kontrollieren?IsUserInRole ruft GetRolesForUser auf?

Hier ist der Aufrufcode

if (Roles.IsUserInRole(CurrentUser.UserName, "Teacher")) { 

Und hier ist die Umsetzung von IsUserInRole

public override bool IsUserInRole(string username, string roleName) { return true; } 

Aber der Code GetRolesForUser wird immer zuerst implementiert:

public override string[] GetRolesForUser(string username) { 
     string[] roles = GetAllRoles(); 
     List<string> userRoles = new List<string>(); 
     foreach (string role in roles) { 
      if (IsUserInRole(username, role)) { 
       userRoles.Add(role); 
      } 
     } 
     return userRoles.ToArray(); 
    } 
+1

schwer zu sehen, wie das möglich ist, ist es eine abstrakte Methode.Poste deine Implementierung davon. –

Antwort

4

Es gibt eine Rolle Anbieters Schicht Microsoft Lösung, die das Zwischenspeichern der Rollen eines Benutzers in einem Cookie ermöglicht Daher muss die GetRolesForUser-Methode des Providers nicht aufgerufen werden. Ich glaube, dass das Cookie-Caching Teil der Roles-Klasse ist. Daher sollte es kompatibel sein, solange Sie es von der RoleProvider-Basisklasse implementieren. Es lohnt sich einen Blick auf den Code in reflector zu werfen, um eine Vorstellung davon zu bekommen, wie MS ihre eigenen abstrakten Klassen implementiert und was die statischen Hilfsklassen tun (Rollen und Mitgliedschaft)

Versuchen Sie cacheRolesInCookie = "true" zum roleManager Element in hinzuzufügen Ihre Konfigurationsdatei und sehen Sie, ob sich der Ablauf ändert.

Da Sie Ihre eigene Implementierung eines RoleProviders verwenden, können Sie auch die IsUserInRole-Methode überschreiben und eine eigene Implementierung bereitstellen, um zu überprüfen, ob ein Benutzer in einer Rolle ist.

UPDATE: Dieser Codeblock innerhalb des Roles.IsUserInRole Methode aufgerufen wird:

IPrincipal currentUser = GetCurrentUser(); 
if (((currentUser != null) && (currentUser is RolePrincipal)) && ((((RolePrincipal) currentUser).ProviderName == Provider.Name) && StringUtil.EqualsIgnoreCase(username, currentUser.Identity.Name))) 
{ 
    flag = currentUser.IsInRole(roleName); 
} 
else 
{ 
    flag = Provider.IsUserInRole(username, roleName); 
} 

Der andere Block ist, was IsUserInRole Ihre benutzerdefinierten Provider-Methode aufrufen wird.

Die Rollen für Ihren Benutzer wurden dem Principal-Objekt noch nicht hinzugefügt. Wenn Sie diesen Schritt noch nicht geschafft haben, OK. Wenn nicht, stellen Sie sicher, dass Sie das tun. Es wird sichergestellt, dass jedes Mal, wenn Sie Roles.IsUserInRole oder User.IsInRole aufrufen, diese Funktionen einen speicherinternen Cache der Rollen für den Benutzer verwenden (sobald sie geladen sind), anstatt jedes Mal zur Datenbank gehen zu müssen. (Obwohl der Basisrollenanbieter und die Rollenmanagerklasse sich darum kümmern sollten.)

Können Sie die Konfigurationsdateieinstellungen für den Rollenanbieter überprüfen? Welche Version von .net benutzt du? Verwalten Sie den Anmeldevorgang manuell oder verwenden Sie das .net-Login-Steuerelement? Haben Sie eine benutzerdefinierte Rollenklasse implementiert? Oder verwenden Sie die System.Web.Security.Roles?

+0

Es wurde versucht, cacheRolesInCookie = "true" für den Rollenanbieter hinzuzufügen, und GetRolesForUser wird weiterhin aufgerufen. – Josh

+0

Haben Sie eine Lösung gefunden? Wenn ich zwei zufällige Zeichenfolgen übergebe, geht es zu InUserInRole, aber wenn ich mein aktives Verzeichnis im username-Parameter übergebe, zwingt es es zu GetRolesForUser !! – Murphybro2

7

Das RoleProvider.IsUserInRole (Benutzername, Passwort) für die Überprüfung Rollen für einen bestimmten Benutzer verwendet wird, die nicht der aktuelle loggon Benutzer (für aktuelle Anmeldebenutzer, es verwendet, auch die Principal.IsInRole statt). Und für RolePrincipal verwendet es immer den GetRolesForUser, um die Rollen zwischenzuspeichern und die Rolle unter der zwischengespeicherten Rollenliste zu überprüfen. (source)

können Benutzer Roles.Provider.IsUserInRole statt Roles.IsUserInRole

+3

Aus welchem ​​Grund arbeitet Provider? – Neeta

Verwandte Themen