我想查找用户所在的组列表。我试过几个解决方案 http://www.codeproject.com/KB/system/everythingInAD.aspx 但没有结果。
此代码给我一个“true”,表示LDAP正在运行:
public static bool Exists(string objectPath)
{
bool found = false;
if (DirectoryEntry.Exists("LDAP://" + objectPath))
found = true;
return found;
}
谢谢,
更新1:
public ArrayList Groups(string userDn, bool recursive)
{
ArrayList groupMemberships = new ArrayList();
return AttributeValuesMultiString("memberOf", "LDAP-Server",
groupMemberships, recursive);
}
public ArrayList AttributeValuesMultiString(string attributeName,
string objectDn, ArrayList valuesCollection, bool recursive)
{
DirectoryEntry ent = new DirectoryEntry(objectDn);
PropertyValueCollection ValueCollection = ent.Properties[attributeName];
IEnumerator en = ValueCollection.GetEnumerator();
while (en.MoveNext())
{
if (en.Current != null)
{
if (!valuesCollection.Contains(en.Current.ToString()))
{
valuesCollection.Add(en.Current.ToString());
if (recursive)
{
AttributeValuesMultiString(attributeName, "LDAP://" +
en.Current.ToString(), valuesCollection, true);
}
}
}
}
ent.Close();
ent.Dispose();
return valuesCollection;
}
我有一个例外:
PropertyValueCollection ValueCollection = ent.Properties[attributeName];
“COMException未处理”
答案 0 :(得分:8)
在.NET 4中,您可以通过以下方式使用新的UserPrincipal
类轻松完成此操作:
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
UserPrincipal user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "your_login");
foreach (var group in user.GetGroups())
{
Console.WriteLine(group.Name);
}
}
您必须添加对System.DirectoryServices.AccountManagement
的引用才能引入所需类型。
答案 1 :(得分:1)
我在stackoverflow上找到了解决方案。 connectionString格式如下:
LDAP://domain.subdomain.com:389/DC=domain,DC=subdomain,DC=com
守则:
public IList<string> GetGroupsByUser(string ldapConnectionString, string username)
{
IList<string> groupList = new List<string>();
var identity = WindowsIdentity.GetCurrent().User;
var allDomains = Forest.GetCurrentForest().Domains.Cast<Domain>();
var allSearcher = allDomains.Select(domain =>
{
var searcher = new DirectorySearcher(new DirectoryEntry(ldapConnectionString));
// Apply some filter to focus on only some specfic objects
searcher.Filter = String.Format("(&(&(objectCategory=person)(objectClass=user)(name=*{0}*)))", username);
return searcher;
});
var directoryEntriesFound = allSearcher
.SelectMany(searcher => searcher.FindAll()
.Cast<SearchResult>()
.Select(result => result.GetDirectoryEntry()));
var memberOf = directoryEntriesFound.Select(entry =>
{
using (entry)
{
return new
{
Name = entry.Name,
GroupName = ((object[])entry.Properties["MemberOf"].Value).Select(obj => obj.ToString())
};
}
});
foreach (var item in memberOf)
foreach (var groupName in item.GroupName)
groupList.Add(groupName);
return groupList;
}
答案 2 :(得分:0)
您确定以上脚本是否正确并且正常运行?我认为它不会考虑嵌套的组成员资格,因此我担心您可能无法获得用户所属的所有组的完整集合。
您看,用户可以是X组的成员,而X组又可以成为Y组的成员,因此用户也可以成为Y组的成员。
我认为上面引用的脚本可能无法展开和枚举嵌套的组成员资格。
如果您有兴趣获得用户所属的全套会员资格,我建议您也考虑这个角度。
我认为还有一些与确定群组成员身份有关的其他问题。如果您有兴趣了解更多信息,请在此处进行讨论:
http://www.activedirsec.org/t39703252/why-is-it-so-hard-to-enumerate-nested-group-memberships-in-a/
我希望它更容易,但似乎并非如此: - (
答案 3 :(得分:0)
使用此代码代替您的版本。这会给你列表。这与原始版本之间的区别在于DirectorySearcher的使用。
public ArrayList AttributeValuesMultiString(string attributeName,
string objectDn, ArrayList valuesCollection, bool recursive)
{
using (DirectoryEntry ent = new DirectoryEntry(objectDn))
{
using (DirectorySearcher searcher = new DirectorySearcher(ent))
{
searcher.PropertiesToLoad.Add(attributeName);
var result = searcher.FindOne();
ResultPropertyValueCollection ValueCollection = result.Properties[attributeName];
IEnumerator en = ValueCollection.GetEnumerator();
while (en.MoveNext())
{
if (en.Current != null)
{
if (!valuesCollection.Contains(en.Current.ToString()))
{
valuesCollection.Add(en.Current.ToString());
if (recursive)
{
AttributeValuesMultiString(attributeName, "LDAP://" +
en.Current.ToString(), valuesCollection, true);
}
}
}
}
}
}
return valuesCollection;
}