2009-12-18 20 views
9

Ich verwende WindowsTokenRoleProvide r, um Active Directory-Gruppenmitgliedschaft in einer ASP.NET-Webanwendung zu bestimmen.Schlechte Leistung mit WindowsTokenRoleProvider

Mein Problem ist, dass die Leistung nicht gut ist, besonders wenn ein Benutzer in vielen Gruppen ist. Als Beispiel, ich bin in 253 (!) Gruppen, und WindowsTokenRoleProvider dauert etwa 150 Sekunden, um festzustellen, welche Gruppen ich bin.

Ich weiß, ich kann Caching verwenden, so dass dies bei nachfolgenden Anforderungen für eine nicht getan wird Benutzer, aber offensichtlich ist es nicht akzeptabel, so lange beim ersten Treffer zu nehmen.

Was sind meine Optionen? Kann ich WindowsTokenRoleProvider zwingen, nur bestimmte Gruppen zu berücksichtigen? (Ich bin nur an 5 interessiert).

Antwort

12

hat einige Tests ergaben, dass mein Problem, dass Aufruf ist:

die Methode GetRolesForUser im RoleProvider
Roles.IsUserInRole(groupName) 

zugreift - die Details jeder Rolle abruft der Benutzer Mitglied ist.

Aber nennen.

Roles.Provider.IsUserInRole(groupName) 

bestimmt, ob der Benutzer in der Gruppe - ohne die Details jeder Rolle Abrufen der Benutzer befindet

seltsam, aber es sieht aus wie Roles.Provider.IsUserInRole verwendet, wird löse mein Problem.

* UPDATE *

Es stellt sich heraus, dass dies nur eine Teil Abhilfe ist; wenn ich unbedingt Berechtigungsprüfungen oder ‚Zulassen‘ und ‚Verweigern‘ in web.comfig, dann WindowsTokenRoleProvider geht nach wie vor und langsam bekommt Details jeder Gruppe der Benutzer ein Mitglied von: o (

Also meine Frage noch ... steht

* UPDATE *

ich löste dies durch Erstellen eine Klasse, die von Windows und überwiegenden GetRolesForUser so dass es nur prüft, ob die Mitgliedschaft in Rollen festgelegt in der Konfiguration erweitert es umfasst Caching zu.

/// <summary> 
/// Retrieve the list of roles (Windows Groups) that a user is a member of 
/// </summary> 
/// <remarks> 
/// Note that we are checking only against each system role because calling: 
/// base.GetRolesForUser(username); 
/// Is _very_ slow if the user is in a lot of AD groups 
/// </remarks> 
/// <param name="username">The user to check membership for</param> 
/// <returns>String array containing the names of the roles the user is a member of</returns> 
public override string[] GetRolesForUser(string username) 
{ 
    // Will contain the list of roles that the user is a member of 
    List<string> roles = null; 

    // Create unique cache key for the user 
    string key = String.Concat(username, ":", base.ApplicationName); 

    // Get cache for current session 
    Cache cache = HttpContext.Current.Cache; 

    // Obtain cached roles for the user 
    if (cache[key] != null) 
    { 
     roles = new List<string>(cache[key] as string[]); 
    } 

    // Was the list of roles for the user in the cache? 
    if (roles == null) 
    { 
     roles = new List<string>(); 

     // For each system role, determine if the user is a member of that role 
     foreach (SystemRoleElement role in WebConfigSection.Settings.SystemRoles) 
     { 
      if (base.IsUserInRole(username, role.Name)) 
      { 
       roles.Add(role.Name); 
      } 
     } 

     // Cache the roles for 1 hour 
     cache.Insert(key, roles.ToArray(), null, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration); 
    } 

    // Return list of roles for the user 
    return roles.ToArray(); 
} 
+0

Vielen Dank, Cocowalla. Genau das, wonach ich gesucht habe. –

+0

Ich bin eigentlich in dem ähnlichen Boot. Also löst es das erste Mal auch das Verbindungsproblem? Wird es länger dauern, bis der Benutzer zum ersten Mal eine Verbindung hergestellt hat und dann die nächsten Male schneller? –

+0

Es dauert ein wenig länger beim ersten Mal, aber nichts wird der Benutzer bemerken (weil wir 'IsUserInRole' verwenden, um nur nach Mitgliedern von Gruppen zu suchen, an denen wir wirklich interessiert sind) – Cocowalla