【问题标题】:Retrieve name of user from Active Directory从 Active Directory 中检索用户名
【发布时间】:2013-05-03 18:24:31
【问题描述】:

诚然,我对 AD 很陌生。我有一个与我们组织内的成员列表绑定的下拉列表。我的最终目标是找到他们的经理姓名,但我是从小步骤开始的。

我已经进行了足够多的搜索以获得正确的结果。我无法从结果中获取正确的数据(通过使用断点等进行验证)

private void cmbUserList_SelectedIndexChanged(object sender, EventArgs e)
{
    var userName = cmbUserList.SelectedValue.ToString();
    DirectorySearcher search = new DirectorySearcher();

    search.Filter = String.Format("(cn={0})", userName);
    search.PropertiesToLoad.Add("givenName");

    SearchResult result = search.FindOne();

    if (result != null)
    {
        // For now I'm trying to just retrieve their name
        lblManagerName.Text = result.GetDirectoryEntry().Name;
    }
}

编辑:我使用的是 .net 4.0 版

有人可以指点我检索正确的名称,然后甚至可以提供链接或资源来提取经理姓名吗?

【问题讨论】:

  • 您使用的是什么版本的 .NET?
  • 抱歉好问题,使用 4.0
  • 你有没有类似:result.Properties("givenName")(0).ToString() ?
  • 它说属性不能像方法一样使用
  • 对不起,那是 vb.net。不确定 C# result.Properties["givenName"][0].ToString() 中的情况如何

标签: c# active-directory


【解决方案1】:

我认为您的代码的问题在于您使用的是“(cn={0})”,用户名。您需要传递完全限定名称,例如

CN=Doe,John,OU=Users,OU=Headquarters,DC=company,DC=net

如果您只有登录 ID,那么下面的代码应该可以工作

DirectorySearcher directorySearcher = new DirectorySearcher("LDAP://RootDSE");
directorySearcher.Filter = "sAMAccountName=" + acctName;
directorySearcher.PropertiesToLoad.Add("manager");
SearchResult searchResult = directorySearcher.FindOne();
if (searchResult != null)
DirectoryEntry user = searchResult.GetDirectoryEntry();

请注意,acctName 是 Windows 登录 ID。如果您想使用 AD 并检查各种属性以及它们的存储方式,请尝试 dsquery 和 dsget 命令行工具。下面的命令将根据登录 id 返回一条用户记录,并显示 manager 字段的内容:

dsquery user domainroot -samid "loginid" | dsget user -samid -mgr

【讨论】:

  • 这不是真的,AD 中的 cn 属性只是全名,所以对于 John Smith => cn=John Smith。我完全支持按 sAMAccountName 查找
  • @Zilog 我相信它在 AD 中是可配置的,我也见过“last,first”。
  • 您在答案中引用的完整路径是 dn(可分辨名称)而不是 cn,因此只要 {0} 是全名,查询 (cn={0}) 是 / 是正确的,并且它不能是您建议的完整路径。您使用 sAMAccountName 的建议是有效的。
【解决方案2】:

帮助类和枚举

public enum ActiveDirectoryObjectClass
{
    Computer,
    User,
    Domain,
    Group,
}

public static class ActiveDirectorySearcher
{
    public static string  GetCurrentDomainName()
    {
        string result;
        using (Domain domain = Domain.GetCurrentDomain())
        {
            result = domain.Name;
        }

        return result;
    }

    public static IEnumerable<T> Select<T>(
        ActiveDirectoryObjectClass activeDirectoryObjectClass,
        Func<DirectoryEntry, ActiveDirectoryObjectClass, bool> condition,
        Func<DirectoryEntry, T> selector
        )
    {
        List<T> list = new List<T>();
        using (Domain domain = Domain.GetCurrentDomain())
        using (DirectoryEntry root = domain.GetDirectoryEntry())
        {
            string filter = string.Format("(objectClass={0})", activeDirectoryObjectClass);
            using (DirectorySearcher searcher = new DirectorySearcher(filter))
            {
                searcher.SearchRoot = root;
                searcher.SearchScope = SearchScope.Subtree;
                using (SearchResultCollection result = searcher.FindAll())
                {
                    foreach (SearchResult item in result)
                    {
                        using (DirectoryEntry entry = item.GetDirectoryEntry())
                        {
                            if (condition(entry, activeDirectoryObjectClass))
                            {
                                list.Add(selector(entry));
                            }
                        }
                    }
                }
            }

        }
        return list;
    }
}

如何使用

    public IEnumerable<User> GetUsers()
    {
        return ActiveDirectorySearcher.Select(
            ActiveDirectoryObjectClass.User,
            (entry, adObjectClass) => string.Compare(entry.SchemaClassName, adObjectClass.ToString(), StringComparison.InvariantCultureIgnoreCase) == 0,
            _ => new User
                     {
                         Name = _.Name.Substring(3),
                         Domain = ActiveDirectorySearcher.GetCurrentDomainName(),
                     });
    }

注意:示例中的用户 - 具有名称、域等属性的自定义类。

【讨论】:

    【解决方案3】:

    查找姓名和/或经理姓名:

    if (sResult != null)
    {
        string userName = sResult.Properties["name"][0].ToString();
        string managerDN = sResult.Properties["manager"][0].ToString();
    
        DirectoryEntry man =  new DirectoryEntry("LDAP://server_name/"+managerDN);
        string managerName = man.Properties["name"][0].ToString();
    
    }
    

    server_name 可以只是 FQDN 的域组件,即 yourcompany.com,这样它将通过 DNS 自行查找目录服务器。

    编辑:

    我还推荐 Sysinternals 的 Active Directory Explorer。它是探索和理解 AD 结构的绝佳工具

    【讨论】:

      猜你喜欢
      • 2017-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-07
      相关资源
      最近更新 更多