2012-03-20 1 views
1

J'ai un code pour vérifier si l'utilisateur est membre d'un groupe. Je l'utilise lors de ma connexion.Vérifier si l'utilisateur est membre d'un groupe

Veuillez noter que j'ai un utilisateur de domaine et un utilisateur local par ex. testdomain\administrator et administrator.

C'est le code que j'utilise:

using (DirectoryEntry groupEntry = new DirectoryEntry("WinNT://./" + userGroupName + ",group")) 
{ 
    foreach (object member in (IEnumerable)groupEntry.Invoke("Members")) 
    { 
     using (DirectoryEntry memberEntry = new DirectoryEntry(member)) 
     { 
      string completeName = memberEntry.Name; 
      DirectoryEntry domainValue = GUIUtility.FindDomain(memberEntry); 
      if (domainValue != null) 
      { 
       completeName = domainValue.Name + "\\" + memberEntry.Name; 
      } 
      Global.logger.Info("completeName from " + userGroupName + " = " + completeName); 
      if (userName.Equals(completeName, StringComparison.InvariantCultureIgnoreCase)) 
      { 
       Global.logger.Debug("IsUserPartOfWindowsGroup returned True with username =" + userName + " , UserGroupName = " + userGroupName); 
       return true; 
      } 
     } 
    } 
    Global.logger.Debug("IsUserPartOfWindowsGroup returned false for username =" + userName + " , UserGroupName = " + userGroupName); 
    return false; 
} 

Ce code fonctionne, mais

DirectoryEntry domainValue = GUIUtility.FindDomain(memberEntry); 

prend beaucoup de temps dans le profileur comme je le vois. Y a-t-il un moyen meilleur/plus rapide de gérer cela?

public static DirectoryEntry FindDomain(DirectoryEntry memberEntry) 
{ 
    if (memberEntry.Parent != null) 
    { 
     if (memberEntry.Parent.SchemaClassName.Equals("domain", StringComparison.InvariantCultureIgnoreCase)) 
     { 
      return memberEntry.Parent; 
     } 
    } 
    return null; 
} 

une autre façon:

DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, userName, Password); 
DirectorySearcher mySearcher = new DirectorySearcher(entry); 
mySearcher.Filter = "(&(objectClass=user)(|(cn=" + userName + ")(sAMAccountName=" + userName + ")))"; 
SearchResult result = mySearcher.FindOne(); 

Global.logger.Info("result == " + result.Path); 
foreach (string GroupPath in result.Properties["memberOf"]) 
{ 
    if (GroupPath.Contains(adminGroupName)) 
    { 
     Global.logger.Info(compUsrNameForEncryption + "exists in " + adminGroupName); 
    } 
} 
+1

On pourrait sans doute aider à mieux si nous savions ce qui était 'GUIUtility.FindDomain'. De plus, les nouvelles classes (ish) [System.DirectoryServices.AccountManagement] (http://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.aspx) rendent ce genre de chose beaucoup plus simple. –

+0

[Question connexe] (http://stackoverflow.com/q/9603777/635634), le code dans [ma réponse] (http://stackoverflow.com/a/9604203/635634) à cette question vous aiderait probablement aussi bien. –

+0

hey babcock .. j'ai ajouté la fonction finddomain. aussi que faire si l'utilisateur ne fait pas partie d'un domaine? – user175084

Répondre

8

C'est assez proche de ce que j'utilise:

public bool IsUserInGroup(string userName, string groupName) 
{ 
    using (var context = new PrincipalContext(ContextType.Machine)) 
    { 
     using (var searcher = new PrincipalSearcher(new UserPrincipal(context) { SamAccountName = userName })) 
     { 
      using (var user = searcher.FindOne() as UserPrincipal) 
      { 
       return user != null && user.IsMemberOf(context, IdentityType.SamAccountName, groupName); 
      } 
     } 
    } 
} 

Je ne l'ai pas testé pour les utilisateurs locaux bien. La logique fonctionne dans mon domaine, je viens de changer PrincipalContext(ContextType.Machine) donc il devrait regarder les utilisateurs locaux maintenant.

Ne pas oublier d'ajouter une référence et instruction à l'aide pour System.DirectoryServices.AccountManagement

+0

hey, j'obtiens une erreur nullrefrenceexception à: return user.IsMemberOf (context, IdentityType.SamAccountName, groupName); – user175084

+0

J'ai également supprimé toutes les vérifications de sécurité, vous obtiendrez cela si 'userName' n'était pas un utilisateur valide. –

+0

Mon code original manquait quelques 'using's ainsi je les ai ajoutés dedans et mis dans la vérification de santé mentale nécessaire. –

1

Peut-être que je manque quelque chose, mais ne pourrais pas vous le faire:

if(Page.User.IsInRole("GROUP NAME")) 
{ 
    // user is in group. do your thing 
} 
else 
{ 
    // user isn't in group 
} 

Works pour moi quand je m faire l'authentification Active Directory sur ASP.NET.

EDIT: Voici un link décrivant l'utilisation de Page.User.IsInRole(). L'authentification Windows doit cependant être utilisée, si vous n'utilisez pas l'authentification Windows, cela ne fonctionnera pas correctement.

EDIT2: Comme il l'authentification Windows n'est pas utilisé c'est ainsi que je le ferais:

DirectoryEntry de = new DirectoryEntry(LDAP Address,user,password); 
DirectorySearcher searcher = new DirectorySearcher(de); 
searcher.Filter = string.Format("(SAMAccountName={0})", user); 
SearchResult result = searcher.FindOne(); 
bool isInGroup = false; 
if (result != null) 
{ 
    DirectoryEntry person = result.GetDirectoryEntry(); 
    PropertyValueCollection groups = person.Properties["memberOf"]; 
    foreach (string g in groups) 
    { 
     if(g.Equals(groupName)) 
     { 
      isInGroup = true; 
      break; 
     } 
    } 
} 
return isInGroup; 
+0

Vous avez peut-être raison, mais je ne suis pas un développeur ASP.NET. Le PO a dit qu'ils sont à la recherche d'une solution qui fonctionne avec les utilisateurs/groupes locaux, donc si votre solution fonctionne pour cela, alors votre réponse est probablement la meilleure. –

+0

@ M.Babcock tant que l'OP utilise l'authentification Windows, alors cela fonctionnera. Si non, alors votre réponse est le chemin à parcourir – Jetti

+0

Je n'utilise pas l'authentification Windows .. et cela est défini dans une classe .. donc la page ne fonctionnera pas .. merci – user175084

Questions connexes