Pergunta

Actualmente tenho algum código que puxa para baixo uma lista de usuários em um grupo e, em seguida, itera através desse grupo para determinar se existe uma determinada conta, mas parece que deveria haver uma forma mais concisa (e talvez mais rápido) maneira de fazer isso.

Este código (VB.NET) tenta usar a propriedade de membro do objeto grupo, mas ele está retornando falso mesmo quando o usuário é membro desse grupo. qualquer um pode ver o que estou fazendo de errado aqui?

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)

FYI:. O GetNetworkObject chamadas apenas retornar um objeto DirectoryEntry, eu confirmaram que o objeto correto está sendo retornado para o objeto de grupo e de usuário

Foi útil?

Solução

Se você estiver em .NET 3.5 stack, System.DirectoryServices .AccountManagement.dll montagem tem um bom API no topo da AD. O método a seguir pode ser implementado para resolver o 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");

Eu não sei como esse método realiza, mas é uma solução limpa.

Outras dicas

Aqui está o que eu usei no passado, em um script VBS que funcionou muito bem:

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

Eu, então, usar um InStr para ver se o usuário é parte desse grupo:

If InStr(strGroups, "MyGroup") Then MyGroupSub

Você pode ser capaz de se adaptar o acima em seu projeto.

A propósito, notei que em seu código que você tem groupdoman como seu último parâmetro para 'grupo' Não tenho certeza se você queria que ser < em> groupdomain ou não:

grupo Dim como DirectoryEntry = GetNetworkObject (GroupDomanName, NetworkObjectType.NetworkGroup, Nome_do_grupo, groupdoman )

vs

grupo Dim como DirectoryEntry = GetNetworkObject (GroupDomanName, NetworkObjectType.NetworkGroup, Nome_do_grupo, groupdomain )

Deixe-me saber se isso ajuda! JFV

Eu encontrei uma resposta que parece trabalho na NET 2.0, é relativamente rápido e supera o possível problema de grupos que contenham mais de 100 itens (que requerem a busca gama)

Aqui está o código que eu acabei com:

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)

Aqui está outra maneira usando o pesquisador diretório e memberOf. Isso é usar os usuários atuais objectSID mas você pode mudar isso para algum outro identificador.

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

Return dSearch.FindOne() IsNot Nothing

Se você vai usar a entrada do usuário que pode conter caracteres inválidos, você deve sempre escapar-los ...

searchName = searchName.Replace("\", "\5c"). _
                                Replace("/", "\2f"). _
                                Replace("*", "\2a"). _
                                Replace("(", "\28"). _
                                Replace(")", "\29")
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top