La mejor manera de determinar rápidamente si una cuenta de usuario es miembro de un grupo de anuncios?

StackOverflow https://stackoverflow.com/questions/368830

Pregunta

Actualmente tengo un código que tira hacia abajo una lista de usuarios en un grupo y luego itera a través de ese grupo para determinar si existe una cuenta determinada, pero parece que debe haber una manera más concisa (y tal vez más rápido) lograr esto.

Este código (VB.NET) intenta utilizar la propiedad de miembro del objeto de grupo, pero se vuelve falsa incluso cuando el usuario es un miembro de dicho grupo. ¿Puede alguien ver lo que estoy haciendo mal aquí?

Dim group As DirectoryEntry =  GetNetworkObject(GroupDomanName, NetworkObjectType.NetworkGroup, GroupName)
Dim user As DirectoryEntry =GetNetworkObject(UserDomainName, NetworkObjectType.NetworkUser, Login)

Return group.Properties("member").Contains(user.Path)

Para su información:. El GetNetworkObject llamadas simplemente devolver un objeto DirectoryEntry, he confirmado que el objeto correcto está siendo devuelto por tanto el objeto de grupo y de usuario

¿Fue útil?

Solución

Si usted está en .NET 3.5 pila, System.DirectoryServices Asamblea .AccountManagement.dll tiene una buena API en la parte superior de la EA. El siguiente método puede ser implementado para resolver el problema:

static bool IsUserMemberOf(string userName, string groupName)
{
    using (var ctx = new PrincipalContext(ContextType.Domain))
    using (var groupPrincipal = GroupPrincipal.FindByIdentity(ctx, groupName))
    using (var userPrincipal = UserPrincipal.FindByIdentity(ctx, userName))
    {
        return userPrincipal.IsMemberOf(groupPrincipal);
    }
}

// Usage:
bool result = IsUserMemberOf("CONTOSO\\john.doe", "CONTOSO\\Administrators");

No sé cómo este método lleva a cabo, pero es una solución limpia.

Otros consejos

Esto es lo que he usado en el pasado en un script VBS que funcionó muy bien:

Set wshNet = CreateObject("WScript.Network")                'Setup connection to the Network
Set fso = CreateObject("Scripting.FileSystemObject")        'Create File System Object for any file manipulations

Set ADSysInfo = CreateObject("ADSystemInfo")                'Setup connection to Active Directory
Set CurrentUser = GetObject("LDAP://" & ADSysInfo.UserName) 'Setup current user to look for in Active Directory
strGroups = LCase(Join(CurrentUser.MemberOf))               'Grabs all the groups the current user is a member of

entonces utilizo un InStr para ver si el usuario es parte de ese grupo:

If InStr(strGroups, "MyGroup") Then MyGroupSub

Usted puede ser capaz de adaptarse lo anterior en su proyecto.

Por cierto, he notado que en su código que tiene groupdoman como su último parámetro para 'grupo' No estoy seguro de si quería que para ser < em> GroupDomain o no:

grupo Dim Como DirectoryEntry = GetNetworkObject (GroupDomanName, NetworkObjectType.NetworkGroup, GroupName, groupdoman )

vs

grupo Dim Como DirectoryEntry = GetNetworkObject (GroupDomanName, NetworkObjectType.NetworkGroup, GroupName, GroupDomain )

Quiero saber si esto ayuda! JFV

encontré una respuesta que parece funcionar en NET 2.0, es relativamente rápido y supera la posible cuestión de los grupos que contienen más de 100 artículos (que requiere la búsqueda por rango)

Este es el código que terminé con:

Dim DSearcher As New DirectorySearcher(group, "(&(objectClass=user)(cn=" + Login + "))", New String() {"member;Range=0-5000"}, SearchScope.OneLevel)                  
group = GetNetworkObject(GroupDomanName, NetworkObjectType.NetworkGroup, GroupName)
user = GetNetworkObject(UserDomainName, NetworkObjectType.NetworkUser, Login)
DSearcher.AttributeScopeQuery = "member"
Return (DSearcher.FindOne() IsNot Nothing)

Aquí hay otra manera usando el buscador directorio y memberOf. Se trata de utilizar los usuarios actuales objectSID pero se puede cambiar para que algún otro identificador.

dSearch.Filter = String.Format("(&(memberOf={0})(objectSid={1}))", groupDN, WindowsIdentity.GetCurrent.User)

Return dSearch.FindOne() IsNot Nothing

si vas a utilizar la entrada del usuario que puede contener caracteres no válidos, siempre debe escapar de ellos ...

searchName = searchName.Replace("\", "\5c"). _
                                Replace("/", "\2f"). _
                                Replace("*", "\2a"). _
                                Replace("(", "\28"). _
                                Replace(")", "\29")
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top