validar usuario query password example ejemplos active c# .net active-directory ldap directoryservices

usuario - query active directory c#



¿Cómo obtener todos los grupos de AD para un usuario en particular? (8)

Aquí está el código que me funcionó:

public ArrayList GetBBGroups(WindowsIdentity identity) { ArrayList groups = new ArrayList(); try { String userName = identity.Name; int pos = userName.IndexOf(@"/"); if (pos > 0) userName = userName.Substring(pos + 1); PrincipalContext domain = new PrincipalContext(ContextType.Domain, "riomc.com"); UserPrincipal user = UserPrincipal.FindByIdentity(domain, IdentityType.SamAccountName, userName); DirectoryEntry de = new DirectoryEntry("LDAP://RIOMC.com"); DirectorySearcher search = new DirectorySearcher(de); search.Filter = "(&(objectClass=group)(member=" + user.DistinguishedName + "))"; search.PropertiesToLoad.Add("samaccountname"); search.PropertiesToLoad.Add("cn"); String name; SearchResultCollection results = search.FindAll(); foreach (SearchResult result in results) { name = (String)result.Properties["samaccountname"][0]; if (String.IsNullOrEmpty(name)) { name = (String)result.Properties["cn"][0]; } GetGroupsRecursive(groups, de, name); } } catch { // return an empty list... } return groups; } public void GetGroupsRecursive(ArrayList groups, DirectoryEntry de, String dn) { DirectorySearcher search = new DirectorySearcher(de); search.Filter = "(&(objectClass=group)(|(samaccountname=" + dn + ")(cn=" + dn + ")))"; search.PropertiesToLoad.Add("memberof"); String group, name; SearchResult result = search.FindOne(); if (result == null) return; group = @"RIOMC/" + dn; if (!groups.Contains(group)) { groups.Add(group); } if (result.Properties["memberof"].Count == 0) return; int equalsIndex, commaIndex; foreach (String dn1 in result.Properties["memberof"]) { equalsIndex = dn1.IndexOf("=", 1); if (equalsIndex > 0) { commaIndex = dn1.IndexOf(",", equalsIndex + 1); name = dn1.Substring(equalsIndex + 1, commaIndex - equalsIndex - 1); GetGroupsRecursive(groups, de, name); } } }

Medí su rendimiento en un bucle de 200 ejecuciones con el código que utiliza el método recursivo AttributeValuesMultiString ; y funcionó 1.3 veces más rápido. Podría ser así debido a nuestra configuración de AD. Sin embargo, ambos fragmentos dieron el mismo resultado.

Revisé this post ya Pero no responde a mi pregunta. Quiero obtener todos los grupos de directorio activo en los que un usuario particular es miembro.

He escrito el siguiente código. Pero no puedo seguir adelante ya que no sé cómo dar el filtro y cómo acceder a las propiedades.

class Program { static void Main(string[] args) { DirectoryEntry de = new DirectoryEntry("LDAP://mydomain.com"); DirectorySearcher searcher = new DirectorySearcher(de); searcher.Filter = "(&(ObjectClass=group))"; searcher.PropertiesToLoad.Add("distinguishedName"); searcher.PropertiesToLoad.Add("sAMAccountName"); searcher.PropertiesToLoad.Add("name"); searcher.PropertiesToLoad.Add("objectSid"); SearchResultCollection results = searcher.FindAll(); int i = 1; foreach (SearchResult res in results) { Console.WriteLine("Result" + Convert.ToString(i++)); DisplayProperties("distinguishedName", res); DisplayProperties("sAMAccouontName", res); DisplayProperties("name", res); DisplayProperties("objectSid", res); Console.WriteLine(); } Console.ReadKey(); } private static void DisplayProperties(string property, SearchResult res) { Console.WriteLine("/t" + property); ResultPropertyValueCollection col = res.Properties[property]; foreach (object o in col) { Console.WriteLine("/t/t" + o.ToString()); } } }

¿Algunas ideas?


Debe utilizar System.DirectoryServices.AccountManagement . Es mucho mas facil Aquí hay un buen article proyecto de código que le da una visión general de todas las clases en esta DLL.

Como señalaste, tu enfoque actual no encuentra el grupo primario. En realidad, es mucho peor de lo que pensabas. Hay algunos casos más que no funcionan, como el grupo local del dominio de otro dominio. Puede consultar here para más detalles. Aquí es cómo se ve el código si cambia a usar System.DirectoryServices.AccountManagement. El siguiente código puede encontrar los grupos inmediatos que este usuario asignó, que incluye el grupo primario.

UserPrincipal user = UserPrincipal.FindByIdentity(new PrincipalContext (ContextType.Domain, "mydomain.com"), IdentityType.SamAccountName, "username"); foreach (GroupPrincipal group in user.GetGroups()) { Console.Out.WriteLine(group); }


El siguiente ejemplo es del artículo de Code Project, (Casi) Todo en Active Directory a través de C # :

// userDn is a Distinguished Name such as: // "LDAP://CN=Joe Smith,OU=Sales,OU=domain,OU=com" public ArrayList Groups(string userDn, bool recursive) { ArrayList groupMemberships = new ArrayList(); return AttributeValuesMultiString("memberOf", userDn, groupMemberships, recursive); } public ArrayList AttributeValuesMultiString(string attributeName, string objectDn, ArrayList valuesCollection, bool recursive) { DirectoryEntry ent = new DirectoryEntry(objectDn); PropertyValueCollection ValueCollection = ent.Properties[attributeName]; IEnumerator en = ValueCollection.GetEnumerator(); while (en.MoveNext()) { if (en.Current != null) { if (!valuesCollection.Contains(en.Current.ToString())) { valuesCollection.Add(en.Current.ToString()); if (recursive) { AttributeValuesMultiString(attributeName, "LDAP://" + en.Current.ToString(), valuesCollection, true); } } } } ent.Close(); ent.Dispose(); return valuesCollection; }

Simplemente llame al método Grupos con el Nombre distinguido para el usuario y pase el indicador bool para indicar si desea incluir membresías anidadas / grupos infantiles en su ArrayList resultante:

ArrayList groups = Groups("LDAP://CN=Joe Smith,OU=Sales,OU=domain,OU=com", true); foreach (string groupName in groups) { Console.WriteLine(groupName); }

Si necesita realizar algún nivel serio de programación de Active Directory en .NET, le recomiendo marcar y revisar el artículo del Proyecto de Código que mencioné anteriormente.


Este código funciona incluso más rápido (dos 1.5 más rápido que mi versión anterior):

public List<String> GetUserGroups(WindowsIdentity identity) { List<String> groups = new List<String>(); String userName = identity.Name; int pos = userName.IndexOf(@"/"); if (pos > 0) userName = userName.Substring(pos + 1); PrincipalContext domain = new PrincipalContext(ContextType.Domain, "riomc.com"); UserPrincipal user = UserPrincipal.FindByIdentity(domain, IdentityType.SamAccountName, userName); // NGeodakov DirectoryEntry de = new DirectoryEntry("LDAP://RIOMC.com"); DirectorySearcher search = new DirectorySearcher(de); search.Filter = "(&(objectClass=group)(member=" + user.DistinguishedName + "))"; search.PropertiesToLoad.Add("cn"); search.PropertiesToLoad.Add("samaccountname"); search.PropertiesToLoad.Add("memberOf"); SearchResultCollection results = search.FindAll(); foreach (SearchResult sr in results) { GetUserGroupsRecursive(groups, sr, de); } return groups; } public void GetUserGroupsRecursive(List<String> groups, SearchResult sr, DirectoryEntry de) { if (sr == null) return; String group = (String)sr.Properties["cn"][0]; if (String.IsNullOrEmpty(group)) { group = (String)sr.Properties["samaccountname"][0]; } if (!groups.Contains(group)) { groups.Add(group); } DirectorySearcher search; SearchResult sr1; String name; int equalsIndex, commaIndex; foreach (String dn in sr.Properties["memberof"]) { equalsIndex = dn.IndexOf("=", 1); if (equalsIndex > 0) { commaIndex = dn.IndexOf(",", equalsIndex + 1); name = dn.Substring(equalsIndex + 1, commaIndex - equalsIndex - 1); search = new DirectorySearcher(de); search.Filter = "(&(objectClass=group)(|(cn=" + name + ")(samaccountname=" + name + ")))"; search.PropertiesToLoad.Add("cn"); search.PropertiesToLoad.Add("samaccountname"); search.PropertiesToLoad.Add("memberOf"); sr1 = search.FindOne(); GetUserGroupsRecursive(groups, sr1, de); } } }


Si tiene una conexión LDAP con un nombre de usuario y contraseña para conectarse a Active Directory, aquí está el código que usé para conectarme correctamente:

using System.DirectoryServices.AccountManagement; // ... // Connection information var connectionString = "LDAP://domain.com/DC=domain,DC=com"; var connectionUsername = "your_ad_username"; var connectionPassword = "your_ad_password"; // Get groups for this user var username = "myusername"; // Split the LDAP Uri var uri = new Uri(connectionString); var host = uri.Host; var container = uri.Segments.Count() >=1 ? uri.Segments[1] : ""; // Create context to connect to AD var princContext = new PrincipalContext(ContextType.Domain, host, container, connectionUsername, connectionPassword); // Get User UserPrincipal user = UserPrincipal.FindByIdentity(princContext, IdentityType.SamAccountName, username); // Browse user''s groups foreach (GroupPrincipal group in user.GetGroups()) { Console.Out.WriteLine(group.Name); }


Simplemente consulte la propiedad "memberOf" y repita la devolución, por ejemplo:

search.PropertiesToLoad.Add("memberOf"); StringBuilder groupNames = new StringBuilder(); //stuff them in | delimited SearchResult result = search.FindOne(); int propertyCount = result.Properties["memberOf"].Count; String dn; int equalsIndex, commaIndex; for (int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++) { dn = (String)result.Properties["memberOf"][propertyCounter]; equalsIndex = dn.IndexOf("=", 1); commaIndex = dn.IndexOf(",", 1); if (-1 == equalsIndex) { return null; } groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1)); groupNames.Append("|"); } return groupNames.ToString();

Esto simplemente rellena los nombres de los grupos en la cadena groupNames, delimitada por tuberías, pero cuando giras puedes hacer lo que quieras con ellos


Utilice tokenGroups :

DirectorySearcher ds = new DirectorySearcher(); ds.Filter = String.Format("(&(objectClass=user)(sAMAccountName={0}))", username); SearchResult sr = ds.FindOne(); DirectoryEntry user = sr.GetDirectoryEntry(); user.RefreshCache(new string[] { "tokenGroups" }); for (int i = 0; i < user.Properties["tokenGroups"].Count; i++) { SecurityIdentifier sid = new SecurityIdentifier((byte[]) user.Properties["tokenGroups"][i], 0); NTAccount nt = (NTAccount)sid.Translate(typeof(NTAccount)); //do something with the SID or name (nt.Value) }

Nota: esto solo recibe grupos de seguridad.


PrincipalContext pc1 = new PrincipalContext(ContextType.Domain, "DomainName", UserAccountOU, UserName, Password); UserPrincipal UserPrincipalID = UserPrincipal.FindByIdentity(pc1, IdentityType.SamAccountName, UserID); searcher.Filter = "(&(ObjectClass=group)(member = " + UserPrincipalID.DistinguishedName + "));