给定 UserPrincipal 对象,如何从 Active Directory 中获取“公司”和“部门”?

Posted

技术标签:

【中文标题】给定 UserPrincipal 对象,如何从 Active Directory 中获取“公司”和“部门”?【英文标题】:How to get "Company" and "Department" from Active Directory given a UserPrincipal object? 【发布时间】:2010-12-19 15:15:38 【问题描述】:

这可能吗?代码示例会很好。

【问题讨论】:

【参考方案1】:

如果用户的部门和公司属性存在,则应该这样做。

DirectoryEntry de = new DirectoryEntry();
de.Path = "LDAP://dnsNameOfYourDC.my.company.com";
DirectorySearcher deSearch = new DirectorySearcher(de);
deSearch.PropertiesToLoad.Add("department");
deSearch.PropertiesToLoad.Add("company");

deSearch.SearchScope = SearchScope.Subtree;
deSearch.Filter = "(&(objectClass=User)(userPrincipalName=MyPrincipalName))";
SearchResultCollection results = deSearch.FindAll():

foreach (SearchResult result in results)

    ResultPropertyCollection props = result.Properties;
    foreach (string propName in props.PropertyNames)
    
       //Loop properties and pick out company,department
       string tmp = (string)props[propName][0];
    

【讨论】:

一点点挑剔:在 LDAP 过滤器中,我更喜欢使用“objectCategory”而不是 objectClass。为什么? objectCategory 是单值的,它在 Active Directory 中被索引,因此搜索者使用 objectCategory 更快。 实际上,如果您使用的是 Windows Server 2008,则 objectClass 属性默认会被索引。如果您使用的是 Windows Server 2000 或 2003,则不会。 这是一个很好的解决方案,非常感谢。尽管我正在专门处理 System.DirectoryServices.AccountManagement.UserPrincipal,但我必须将下面的内容标记为正确。【参考方案2】:

实际上,问题是如何获取 .NET 3.5 (System.DirectoryServices.AccountManagement.)UserPrincipal-object 的两个属性,而不是 userPrincipalName

这里如何使用extension method:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

namespace MyExtensions

    public static class AccountManagementExtensions
    

        public static String GetProperty(this Principal principal, String property)
        
            DirectoryEntry directoryEntry = principal.GetUnderlyingObject() as DirectoryEntry;
            if (directoryEntry.Properties.Contains(property))
                return directoryEntry.Properties[property].Value.ToString();
            else
                return String.Empty;
        

        public static String GetCompany(this Principal principal)
        
            return principal.GetProperty("company");
        

        public static String GetDepartment(this Principal principal)
        
            return principal.GetProperty("department");
        

    

上面的代码在大多数情况下都可以工作(也就是说,它适用于标准的文本/字符串单值 Active Directory 属性)。您需要修改代码并为您的环境添加更多错误处理代码。

您可以通过将“扩展类”添加到您的项目中来使用它,然后您可以这样做:

PrincipalContext domain = new PrincipalContext(ContextType.Domain);
UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(domain, "youruser");
Console.WriteLine(userPrincipal.GetCompany());
Console.WriteLine(userPrincipal.GetDepartment());
Console.WriteLine(userPrincipal.GetProperty("userAccountControl"));

(顺便说一句;这对扩展属性很有用 - too bad it won't be in C# 4 either。)

【讨论】:

您还可以查看 Principal Extensions (msdn.microsoft.com/en-us/library/bb552835.aspx) 以创建具有所需特定属性的自定义主体。 您将如何进行“设置”方法并保存值? @PerNoalt 感谢您的代码,但没有更短的方法可以直接获取属性,例如:直接从 UserPrincipal 获取部门而不使用扩展? 这个扩展太棒了!感谢您发布它。

以上是关于给定 UserPrincipal 对象,如何从 Active Directory 中获取“公司”和“部门”?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 UserPrincipal 类设置 AD-LDS 用户密码

UserPrincipal.GetGroups vs. UserPrincipal.GetAuthorizationGroups?

UserPrincipal.GetAuthorizationGroups() 方法出错

UserPrincipal.FindByIdentity 在 64 位 WinPE 下的 C# 中失败

有没有办法为 UserPrincipal.FindByIdentity() 启用推荐追踪?

使用 UserPrincipal 类创建新的 AD-LDS 用户总是失败