递归查询LDAP组成员资格

我正在编写一个基于MVC(.NET 4.0)的网站,该网站需要我公司LDAP服务器的登录凭据。 我的代码需要的是仅允许属于某个组的用户。 例如,我可能正在寻找属于“企业IT”小组的用户。 我的凭据可能是“系统管理员”组的一部分,该组是“企业IT”的子组。 我正在使用表单身份validation。

如何以递归方式检查用户登录时所在的组?

对于来自搜索此类查询的其他人,以下是我在我的应用程序中的操作方法:

关键是1.2.840.113556.1.4.1941扩展搜索filter。 由于此特定filter仅适用于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; } } 

如果要检查特定用户的成员身份,请绑定到相关AD对象并检索tokenGroups属性。 它包含二进制forms的所有直接和间接组成员资格 – 它是一个字节数组的数组。 每个字节数组都可以传递给SecurityIdentifier类的构造函数,然后转换为NTAccount,其中包含以明文forms显示的组的名称。

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

这是一个完全不同的解决方案。 测试并在我的域上工作。 一些注意事项:您必须正确使用DirectorySearcher.Filter。 为AD层次结构添加多个OU(按相反顺序,自下而上)。 还要注意,为了安全起见,我在“using”语句中处理了一些对象,因为它们实现了System.ComponentModel.Component,而System.ComponentModel.Component又实现了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 (eg, 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 } }