9

我目前有一些代码可以拉下组中的用户列表,然后遍历该组以确定给定帐户是否存在,但似乎应该有一种更简洁(也许更快)的方法来完成此操作。

此代码 (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

4 回答 4

19

如果您在 .NET 3.5 堆栈上,System.DirectoryServices.AccountManagement.dll 程序集在 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");

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

于 2008-12-15T16:21:51.563 回答
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”的最后一个参数不确定您是否希望它是groupdomain

暗组作为 DirectoryEntry = GetNetworkObject(GroupDomanName, NetworkObjectType.NetworkGroup, GroupName, groupdoman )

对比

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

让我知道这是否有帮助!联合部队

于 2008-12-15T16:43:52.563 回答
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)
于 2008-12-15T16:52:16.353 回答
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")
于 2008-12-15T20:48:53.800 回答