如何在C#中访问Active Directory用户组的url属性
解决AD用户memberOf组的URL属性获取问题
核心思路
用户当前代码中memberOf返回的是组的区别名(DN),仅截取组名无法获取组的URL等属性。需要通过组的DN创建DirectoryEntry实例,直接读取组的对应属性。
步骤1:修改实体类结构
原ActiveDirectoryUser的MemberOf为PropertyValueCollection,无法存储组的多属性信息,需新增组实体类并替换属性类型:
public class ActiveDirectoryUser { public string SamId { get; set; } public string NameFirst { get; set; } public string NameLast { get; set; } public string OfficePhone { get; set; } public string EmailAddress { get; set; } public string JobTitle { get; set; } // 替换为自定义组列表,存储完整组属性 public List<AdGroup> MemberOf { get; set; } = new List<AdGroup>(); } public class AdGroup { public string Name { get; set; } public string Url { get; set; } public string GroupType { get; set; } public string Description { get; set; } }
步骤2:修改搜索方法逻辑
遍历用户的memberOf项(组DN),逐个创建组的DirectoryEntry并读取属性:
public static ActiveDirectoryUser SearchActiveDirectoryUserDetail(string samAccount) { var user = new ActiveDirectoryUser { SamId = samAccount }; var ldapPath = "LDAP://" + Environment.UserDomainName; var searchFilter = $"(&(objectCategory=person)(objectClass=user)(sAMAccountName={samAccount}))"; string[] searchProperties = { "samaccountname", "givenName", "sn", "telephoneNumber", "mail", "title", "memberOf" }; try { using (var parentEntry = new DirectoryEntry(ldapPath)) using (var directorySearcher = new DirectorySearcher(parentEntry, searchFilter, searchProperties)) using (var searchResultCollection = directorySearcher.FindAll()) { if (searchResultCollection.Count == 0) return null; foreach (SearchResult searchResult in searchResultCollection) { var entry = searchResult.GetDirectoryEntry(); if (entry == null) continue; // 填充用户基础信息 user.SamId = entry.Properties["samaccountname"].Value?.ToString() ?? string.Empty; user.NameFirst = entry.Properties["givenName"].Value?.ToString() ?? string.Empty; user.NameLast = entry.Properties["sn"].Value?.ToString() ?? string.Empty; user.OfficePhone = entry.Properties["telephoneNumber"].Value?.ToString() ?? string.Empty; user.EmailAddress = entry.Properties["mail"].Value?.ToString() ?? string.Empty; user.JobTitle = entry.Properties["title"].Value?.ToString() ?? string.Empty; // 遍历并读取每个组的属性 if (entry.Properties["memberOf"] != null && entry.Properties["memberOf"].Count > 0) { foreach (var groupDn in entry.Properties["memberOf"]) { var groupDnStr = groupDn.ToString(); using (var groupEntry = new DirectoryEntry($"LDAP://{groupDnStr}")) { var adGroup = new AdGroup(); // 提取组名 var startIndex = groupDnStr.IndexOf("CN=", StringComparison.Ordinal) + 3; var endIndex = groupDnStr.IndexOf(",", startIndex, StringComparison.Ordinal); adGroup.Name = groupDnStr.Substring(startIndex, endIndex - startIndex); // 读取组的URL属性(AD中LDAP属性名为"url") adGroup.Url = groupEntry.Properties["url"].Value?.ToString() ?? string.Empty; // 读取组类型、描述等属性 adGroup.GroupType = groupEntry.Properties["groupType"].Value?.ToString() ?? string.Empty; adGroup.Description = groupEntry.Properties["description"].Value?.ToString() ?? string.Empty; user.MemberOf.Add(adGroup); } } } } } } catch { // 可按需添加异常日志、错误处理逻辑 } return user; }
关键注意事项
- 属性名称准确性:AD中属性的LDAP名称需严格对应,比如URL属性的LDAP名就是
url,自定义属性需提前确认对应名称。 - 权限问题:确保运行程序的账号拥有读取AD组属性的权限,若部分组无法访问,可在组读取逻辑内添加单独的try-catch块,避免影响其他组的获取。
- 空值处理:所有属性读取都做了空值判断,避免
NullReferenceException。
内容的提问来源于stack exchange,提问作者Zalu
相关产品推荐
相关产品推荐

