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

发布于 2024-07-10 13:09:08 字数 516 浏览 9 评论 0原文

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

此代码 (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 对象,我已确认为组和用户对象返回了正确的对象。

I currently have some code that pulls down a list of users in a group and then iterates through that group to determine if a given account exists, but it seems like there ought to be a more concise (and perhaps faster) way to accomplish this.

This code (VB.NET) attempts to use the member property of the group object, but it is returning false even when the user is a member of that group. Can anyone see what I am doing wrong here?

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: The GetNetworkObject calls just return a directoryEntry object, I have confirmed that the correct object is being returned for both the group and user object.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夜夜流光相皎洁 2024-07-17 13:09:08

如果您使用 .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");

我不知道此方法的执行情况,但它是一个干净的解决方案。

If you are on .NET 3.5 stack, System.DirectoryServices.AccountManagement.dll assembly has a nice API on top of AD. The following method can be implemented to solve your issue:

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

I don't know how this method performs but it is a clean solution.

要走就滚别墨迹 2024-07-17 13:09:08

以下是我过去在 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 或不:

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

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

请告诉我这是否有帮助! JFV

Here is what I've used in the past in a VBS Script that worked very well:

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

I then use an InStr to see if the user is part of that group:

If InStr(strGroups, "MyGroup") Then MyGroupSub

You might be able to adapt the above in your project.

By the way, I noticed that in your code you have groupdoman as your last parameter for 'group' Not sure if you wanted that to be groupdomain or not:

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

vs

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

Let me know if this helps! JFV

自我难过 2024-07-17 13:09:08

我找到了一个似乎在 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)

I found an answer that seems to work in NET 2.0, is relatively quick and overcomes the possible issue of groups containing more than 100 items (which require range searching)

Here is the code that I wound up with:

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)
空袭的梦i 2024-07-17 13:09:08

这是使用目录搜索器和 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")

Here's another way using the directory searcher and memberOf. This is using the current users objectSID but you could change that to some other identifier.

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

Return dSearch.FindOne() IsNot Nothing

if your going to use user input which might contain invalid characters, you should always escape them...

searchName = searchName.Replace("\", "\5c"). _
                                Replace("/", "\2f"). _
                                Replace("*", "\2a"). _
                                Replace("(", "\28"). _
                                Replace(")", "\29")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文