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

时间:2021-10-05 02:59:39

I have a function that retrieves the fullname of a user based on user name and domain. This function runs in ASP.NET thread under an impersonated user. When I use Directory searcher on a remote AD branch, I believe I'm getting the SID number instead of the property (cannot verify it occurs on a different box).

我有一个函数,它根据用户名和域检索用户的全名。此函数在模拟用户下的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 个解决方案

#1


What version of the .NET framework are you working against? The AD stuff has been revamped quite extensively in .NET 3.5, and offers strongly typed constructs for User and groups and stuff like that now.

你正在使用什么版本的.NET框架? AD的东西在.NET 3.5中得到了相当广泛的改进,并且为用户和组提供了强类型的构造,现在就像这样。

Check out the excellent article "Managing Directory Security Principals in the .NET Framework 3.5" by my buddies Joe Kaplan and Ethan Wilansky on MSDN. Excellent stuff indeed.

查看我的好友Joe Kaplan和Ethan Wilansky在MSDN上的优秀文章“在.NET Framework 3.5中管理目录安全主体”。确实很棒的东西。

First of all, you get a class called UserPrincipal which is strongly typed, e.g. all the basic properties are properties on your object. Very helpful indeed.

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

Secondly, you get a nice "query-by-example" method using PrincipalSearcher - check out this sample from Joe and Ethan's article:

其次,使用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);
}

If there's any chance at all, try to get to .NET 3.5 for your AD stuff !

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

Marc

#2


I've wrapped up AD into a handy helper library and have always used this method:

我把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 is a custom class that maps a SearchResult to strong typed properties.

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

I am not sure what your specific problem is, but this has always worked for me.

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

EDIT: Comparing our code, I see you are not telling search to preload the property...That is probably your problem.

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

#1


What version of the .NET framework are you working against? The AD stuff has been revamped quite extensively in .NET 3.5, and offers strongly typed constructs for User and groups and stuff like that now.

你正在使用什么版本的.NET框架? AD的东西在.NET 3.5中得到了相当广泛的改进,并且为用户和组提供了强类型的构造,现在就像这样。

Check out the excellent article "Managing Directory Security Principals in the .NET Framework 3.5" by my buddies Joe Kaplan and Ethan Wilansky on MSDN. Excellent stuff indeed.

查看我的好友Joe Kaplan和Ethan Wilansky在MSDN上的优秀文章“在.NET Framework 3.5中管理目录安全主体”。确实很棒的东西。

First of all, you get a class called UserPrincipal which is strongly typed, e.g. all the basic properties are properties on your object. Very helpful indeed.

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

Secondly, you get a nice "query-by-example" method using PrincipalSearcher - check out this sample from Joe and Ethan's article:

其次,使用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);
}

If there's any chance at all, try to get to .NET 3.5 for your AD stuff !

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

Marc

#2


I've wrapped up AD into a handy helper library and have always used this method:

我把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 is a custom class that maps a SearchResult to strong typed properties.

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

I am not sure what your specific problem is, but this has always worked for me.

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

EDIT: Comparing our code, I see you are not telling search to preload the property...That is probably your problem.

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