快速确定用户帐户是否是AD组成员的最佳方法?

时间:2008-12-15 16:02:28

标签: active-directory ldap adsi directoryentry

我目前有一些代码可以提取组中的用户列表,然后遍历该组以确定某个帐户是否存在,但似乎应该有更简洁(也许更快)的方式做到这一点。

此代码(VB.NET)尝试使用组对象的成员属性,但即使用户是该组的成员,它也会返回false。谁能看到我在这里做错了什么?

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)

仅供参考:GetNetworkObject调用只返回一个directoryEntry对象,我已经确认正在为组和用户对象返回正确的对象。

4 个答案:

答案 0 :(得分:18)

如果您使用的是.NET 3.5堆栈,System.DirectoryServices.AccountManagement.dll assembly在AD之上有一个很好的API。可以使用以下方法来解决您的问题:

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");

我不知道这种方法是如何执行的,但它是一个干净的解决方案。

答案 1 :(得分:2)

以下是我过去在VBS脚本中使用过的非常好的内容:

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

然后我使用InStr查看用户是否属于该组:

If InStr(strGroups, "MyGroup") Then MyGroupSub

您可以在项目中调整上述内容。

顺便说一下,我注意到你的代码中有 groupdoman 作为'group'的最后一个参数不确定你是否希望 < em> groupdomain 与否:

Dim group As DirectoryEntry = GetNetworkObject(GroupDomanName,NetworkObjectType.NetworkGroup,GroupName, groupdoman

VS

Dim group As DirectoryEntry = GetNetworkObject(GroupDomanName,NetworkObjectType.NetworkGroup,GroupName, groupdomain

如果这有帮助,请告诉我! JFV

答案 2 :(得分:1)

我发现一个似乎在.NET 2.0中有效的答案相对较快,并且克服了包含100多个项目(需要搜索范围)的组的可能问题

以下是我结束的代码:

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)

答案 3 :(得分:1)

这是使用目录搜索器和memberOf的另一种方式。这是使用当前用户objectSID,但您可以将其更改为其他标识符。

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

Return dSearch.FindOne() IsNot Nothing

如果您要使用可能包含无效字符的用户输入,则应始终将其转义...

searchName = searchName.Replace("\", "\5c"). _
                                Replace("/", "\2f"). _
                                Replace("*", "\2a"). _
                                Replace("(", "\28"). _
                                Replace(")", "\29")