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

あなたのプロジェクトで上記を適応させることができるかもしれません。

ところで、あなたのコードでは、'group' の最後のパラメーターとしてgroupdomanがあることに気付きました。それをgroupdomainにしたいかどうかはわかりません:

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

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

これが役立つかどうか教えてください!JFV

于 2008-12-15T16:43:52.563 に答える
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 に答える
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 に答える