2011-10-19 15 views
3

私は、企業のLDAPサーバからのログイン資格情報を必要とするMVCベース(.NET 4.0)のWebサイトを作成しています。私のコードが必要とするのは、特定のグループの一部であるユーザーだけを許可することです。たとえば、「Corporate IT」グループの一員であるユーザーを探すことができます。私の資格情報は、 "Corporate IT"のサブグループである "System Admins"グループの一部である可能性があります。私はフォーム認証を使用しています。LDAPグループのメンバシップを再帰的にクエリしています

ログイン時にユーザーがどのグループにいるかを再帰的に確認するにはどうすればよいですか?

答えて

1

特定のユーザーのメンバーシップを確認する場合は、該当するADオブジェクトにバインドし、tokenGroups属性を取得します。バイナリ形式の直接的および間接的なグループメンバーシップがすべて含まれています。これはバイト配列の配列です。各バイト配列は、SecurityIdentifierクラスのコンストラクタから渡され、その後、クリアテキストでグループの名前を含むNTAccountに変換されます。

var sids = new IdentityReferenceCollection(); 
foreach (byte[] group in tokenGroups) 
{ 
    sids.Add(new SecurityIdentifier(group, 0)); 
} 
var accounts = sids.Translate(typeof(NTAccount)); 
+0

この技術は動作しますが、配布リストは含まれず、セキュリティグループのみが含まれます。誰かが配布リストを取得する方法を知っていれば、それは素晴らしいでしょう。 –

+0

実際、私はグループの列挙を探しています。 – MarkP

+0

配布グループを含むグループ列挙? –

0

ここでは全く異なる解決策があります。私のドメインをテストして作業しています。いくつかの注意事項:あなたは正しいDirectorySearcher.Filterを取得する必要があります。 AD階層に複数のOUを追加します(逆順、ボトムアップ)。また、安全であるように、私はSystem.ComponentModel.Componentを実装しているので、 "using"ステートメントにいくつかのオブジェクトを置いています。これはIDisposable ...を実装しています。誰がここで、クエリのこのタイプの検索からここに来るために

public bool IsUserMemberOfGroup(string groupName) 
    { 
     // CN is your distro group name. OU is the object(s) in your AD hierarchy. DC is for your domain and domain suffix (e.g., yourDomain.local) 
     string searchFilter = String.Format(@"(&(objectcategory=user)(sAMAccountName=markp)(memberof=CN={0},OU=System Admins,OU=USA,DC=yourDomain,DC=local))", groupName); 
     SearchResultCollection searchResult; 

     using (var dirEntry = new DirectoryEntry("LDAP://dc=yourDomain,dc=local")) 
     { 
      using (var dirSearch = new DirectorySearcher(dirEntry)) 
      { 
       dirSearch.SearchScope = SearchScope.Subtree; 
       dirSearch.Filter = searchFilter; 
       searchResult = dirSearch.FindAll(); 
      } 
     } 
     if (searchResult.Count <= 0 || searchResult == null) { 
      return false; // not in group 
     } 
     else { 
      return true; // in group 
     } 
    } 
+1

MSDNによると、GetGroupsメソッドはグループメンバシップの再帰的な検索を実行しないため、間接的なグループメンバシップは返されません。 GetAuthorizationGroupsは再帰ルックアップを実行できますが、私のアプローチと同じように、セキュリティグループに限定されています。 –

+0

あなたはヘニングの権利を持っています。良いキャッチ。私はその質問がいくらか難読化されるかもしれないと思う。 @MarkPこれについてもっと考えてみると、あなたは実際にすべてのグループを見る/リストする必要はありませんか?ユーザーが特定の(ADディストリビューション)グループにいることを検証するだけです。あれは正しいですか?もしそうなら、それは実行可能です。それ以外の場合は、再帰を見ているか、PowerShellを呼び出すことさえあります。 –

+0

はい、特定のユーザーがより大きなグループの一部であることを確認する必要があります。 – MarkP

5

は、私は自分のアプリケーションでそれをやった方法です:

キーが1.2.840.113556.1.4.1941拡張検索フィルタです。この特定のフィルタはDNのみで動作するため、チェックしたいユーザーのDNを取得してから、この特定のユーザーがチェーン内のいずれかのグループのメンバーであるかどうかを確認するためにグループを照会します。

internal const string UserNameSearchFilter = "(&(objectCategory=user)(objectClass=user)(|(userPrincipalName={0})(samAccountName={0})))"; 
internal const string MembershipFilter = "(&(objectCategory=group)(objectClass=group)(cn=MyGroup)(member:1.2.840.113556.1.4.1941:={0}))"; 

using (var de = new DirectoryEntry(AppSettings.LDAPRootContainer, AppSettings.AdminUser, AppSettings.AdminPassword, AuthenticationTypes.FastBind)) 
using (var ds = new DirectorySearcher(de) { Filter = string.Format(UserNameSearchFilter, username) }) 
{ 

    ds.PropertiesToLoad.AddRange(new[] { "distinguishedName" }); 

    var user = ds.FindOne(); 

    if (user != null) 
     using (var gds = new DirectorySearcher(de) { PropertyNamesOnly = true, Filter = string.Format(MembershipFilter, user.Properties["distinguishedName"][0] as string) }) 
     { 
      gds.PropertiesToLoad.AddRange(new[] { "objectGuid" }); 
      return gds.FindOne() != null; 
     } 
} 
関連する問題