如何克服Active Directory搜索中的后期绑定

时间:2009-03-09 18:14:52

标签: c# active-directory

我有一个函数可以根据用户名和域检索用户的全名。此函数在模拟用户下的ASP.NET线程中运行。 当我在远程AD分支上使用目录搜索器时,我相信我得到的是SID号而不是属性(无法验证它是否出现在另一个盒子上)。

public string GetUserFullName(string userName, string domainName)
{  
    DirectoryEntry rootEntry = new DirectoryEntry("GC://dc=company,dc=net");
    string filter = string.Format("(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(userPrincipalName={0}@{1}.company.net))", userName, domainName);
    DirectorySearcher searcher = new DirectorySearcher(rootEntry, filter, new string[] { "displayName" });
    rootEntry.AuthenticationType = AuthenticationTypes.Secure;
    searcher.PageSize = 1000;
    searcher.ServerTimeLimit = new TimeSpan(0, 10, 0);
    searcher.ReferralChasing = ReferralChasingOption.All;
    searcher.Asynchronous = false;

    SearchResult result = searcher.FindOne();
    if (result != null)
    {
        return (string) result.Properties["displayName"][0];
    }
    else
    {
        throw new Exception("Active Directory could not resolve your user name");
    }

}

2 个答案:

答案 0 :(得分:3)

您正在使用哪种版本的.NET框架? AD的内容已经在.NET 3.5中得到了广泛的改进,并且为用户和组以及类似的东西提供了强类型的构造。

在我的好友Joe Kaplan和Ethan Wilansky的MSDN上查看优秀文章“Managing Directory Security Principals in the .NET Framework 3.5”。确实很棒。

首先,你得到一个名为UserPrincipal的类,它是强类型的,例如所有基本属性都是对象的属性。非常有帮助。

其次,使用PrincipalSearcher获得一个很好的“逐个查询”方法 - 查看Joe和Ethan的文章中的这个示例:

// create a principal object representation to describe
// what will be searched 
UserPrincipal user = new UserPrincipal(adPrincipalContext);

// define the properties of the search (this can use wildcards)
user.Enabled = false;
user.Name = "user*";

// create a principal searcher for running a search operation
PrincipalSearcher pS = new PrincipalSearcher();

// assign the query filter property for the principal object 
// you created
// you can also pass the user principal in the 
// PrincipalSearcher constructor
pS.QueryFilter = user;

// run the query
PrincipalSearchResult<Principal> results = pS.FindAll();

Console.WriteLine("Disabled accounts starting with a name of 'user':");
foreach (Principal result in results)
{
    Console.WriteLine("name: {0}", result.Name);
}

如果有任何机会,请尝试使用.NET 3.5获取AD内容!

马克

答案 1 :(得分:0)

我已将AD包装到一个方便的帮助程序库中,并始终使用此方法:

    /// <summary>
    /// Returns AD information for a specified userID.
    /// </summary>
    /// <param name="ntID"></param>
    /// <returns></returns>
    public ADUser GetUser(string ntID)
    {          
        DirectorySearcher search = new DirectorySearcher();        

        search.Filter = String.Format("(cn={0})", ntID);

        search.PropertiesToLoad.Add("mail");
        search.PropertiesToLoad.Add("givenName");
        search.PropertiesToLoad.Add("sn");
        search.PropertiesToLoad.Add("displayName");
        search.PropertiesToLoad.Add("userPrincipalName");
        search.PropertiesToLoad.Add("cn");

        SearchResult result = search.FindOne();

        return new ADUser(result);
    }

ADUser是一个自定义类,它将SearchResult映射到强类型属性。

我不确定你的具体问题是什么,但这一直对我有用。

编辑:比较我们的代码,我发现你没有告诉搜索预先加载属性......这可能是你的问题。