[英]Get additional Active directory attributes from Principal instead of DirectorySearcher's SearchResult
I would like to get some additional AD attributes from the AD user.我想从 AD 用户那里获得一些额外的 AD 属性。 I want to use PrincipalSearcher
instead of DirectorySearcher
.我想使用PrincipalSearcher
而不是DirectorySearcher
。
What I did was get the underlyingSearcher of the PrincipalSearcher and called FindOne() method.我所做的是获取 PrincipalSearcher 的基础搜索器并调用 FindOne() 方法。 I don't like to use GetUnderlyingSearcher from PrincipalSearcher, but apparently it works.我不喜欢使用 PrincipalSearcher 的 GetUnderlyingSearcher,但显然它有效。
The code works, but I'm wondering if there is a way to read additional properties/Ad attributes from Principal
该代码有效,但我想知道是否有办法从Principal
读取其他属性/广告属性
Principal match = principalSearcher.FindOne();
Additionally could below code have some problems because we are using the underlyingSearcher (DirectorySearcher) methods.此外,下面的代码可能会出现一些问题,因为我们使用的是底层搜索器(DirectorySearcher)方法。
I find PrincipalSearcher
more higher level and also if I would use DirectorySearcher the ldapPath must be defined eg var ldapPath = "DC=corp,DC=ad,DC=example,DC=com";
我发现PrincipalSearcher
级别更高,如果我要使用 DirectorySearcher,则必须定义eg var ldapPath = "DC=corp,DC=ad,DC=example,DC=com";
It's just less lines of code.它只是更少的代码行。
public AdSimpleObject GetUser(string userName, string domainName)
{
PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, domainName);
UserPrincipal userPrincipal = new UserPrincipal(principalContext);
userPrincipal.SamAccountName = userName; // where condition
using (PrincipalSearcher principalSearcher = new PrincipalSearcher(userPrincipal))
{
using (DirectorySearcher ds = (DirectorySearcher)principalSearcher.GetUnderlyingSearcher())
{
// get only properties we need, therefore search performance is increased
ds.PropertiesToLoad.Clear();
ds.PropertiesToLoad.AddRange(new string[]
{
"sAMAccountType",
"sAMAccountName",
"userPrincipalName",
"msDS-PrincipalName"
});
SearchResult match = ds.FindOne();
if (match != null)
{
AdSimpleObject ado = this.CreateAdSimpleObject(match);
return ado;
}
return null;
}
}
}
public class AdSimpleObject
{
public string AdsPath { get; set; }
public int SamAccountType { get; set; }
public string SamAccountName { get; set; }
public string MsDsPrincipalName { get; set; }
public string UserPrincipalName { get; set; }
}
private AdSimpleObject CreateAdSimpleObject(SearchResult searchItem)
{
ResultPropertyCollection props = searchItem.Properties;
string adsPath = props["adspath"]?.OfType<string>().ToList().FirstOrDefault() ?? string.Empty;
int samAccountType = props["sAMAccountType"]?.OfType<int>().ToList().FirstOrDefault() ?? 0;
string samAccountName = props["sAMAccountName"]?.OfType<string>().ToList().FirstOrDefault() ?? string.Empty;
string userPrincipalName = props["userPrincipalName"]?.OfType<string>().ToList().FirstOrDefault() ?? string.Empty;
string msDsPrincipalName = props["msDS-PrincipalName"]?.OfType<string>().ToList().FirstOrDefault() ?? string.Empty;
return new AdSimpleObject
{
AdsPath = adsPath,
SamAccountType = samAccountType,
SamAccountName = samAccountName,
UserPrincipalName = userPrincipalName,
MsDsPrincipalName = msDsPrincipalName
};
}
I'm wondering if there is a way to read additional properties/Ad attributes from
Principal
我想知道是否有办法从Principal
读取其他属性/广告属性
You would use the DirectoryEntry
object returned from Principal.GetUnderlyingObject
:您将使用从Principal.GetUnderlyingObject
返回的DirectoryEntry
object :
Principal match = principalSearcher.FindOne();
var de = (DirectoryEntry) match.GetUnderlyingObject();
de.RefreshCache(new string[] {"someAttribute"});
var someAttribute = de.Properties["someAttribute"].Value;
Doing this will go back out to AD to get the attributes, instead of using the data that was retrieved in the search.这样做会将 go 返回到 AD 以获取属性,而不是使用在搜索中检索到的数据。 The use of RefreshCache
is to tell it to only get the attributes you are interested in. Otherwsie, if you use DirectoryEntry.Properties
right away, it will go out to AD and get all attributes that have a value , which is unlikely what you need, and will just take extra time for no reason.使用RefreshCache
是告诉它只获取您感兴趣的属性。否则,如果您立即使用DirectoryEntry.Properties
,它将 go 输出到 AD 并获取所有具有 value 的属性,这不太可能是您需要的,并且会无缘无故地花费额外的时间。
Additionally could below code have some problems because we are using the underlyingSearcher (DirectorySearcher) methods.此外,下面的代码可能会出现一些问题,因为我们使用的是底层搜索器(DirectorySearcher)方法。
Not at all.一点也不。 That code is no different than just making your own DirectorySearcher
and using it.该代码与制作您自己的DirectorySearcher
并使用它没有什么不同。 In fact, with the way you've written this code, there is no real point to using UserPrincipal
/ PrincipalSearcher
at all.事实上,以您编写此代码的方式,使用UserPrincipal
/ PrincipalSearcher
根本没有真正意义。 The only thing it's done for you is build the query string.它为您做的唯一一件事就是构建查询字符串。
The whole AccountManagement
namespace is just a wrapper around DirectoryEntry
/ DirectorySearcher
.整个AccountManagement
命名空间只是DirectoryEntry
/ DirectorySearcher
的包装。 It makes things easier for the programmer (in some cases, not all), but it does so at the cost of performance.它使程序员的事情变得更容易(在某些情况下,不是全部),但这样做是以牺牲性能为代价的。
If you use DirectoryEntry
/ DirectorySearcher
yourself directly, you have far more control over how much data is retrieved from AD, and how often network requests are made.如果您自己直接使用DirectoryEntry
/ DirectorySearcher
,您可以更好地控制从 AD 中检索到的数据量以及发出网络请求的频率。 Those translate into less time taken.这些转化为更少的时间。 If you're just searching for one account, then it won't make much of a difference.如果您只是在搜索一个帐户,那么它不会有太大的不同。 But if you're searching for large groups of users, or looping over a large list of users, it can make a huge difference.但是,如果您正在搜索大量用户,或者循环访问大量用户列表,则可能会产生巨大的影响。
I wrote an article about optimizing performance when talking to AD (specifically with DirectoryEntry
/ DirectorySearcher
): Active Directory: Better performance我写了一篇关于在与 AD 交谈时优化性能的文章(特别是使用DirectoryEntry
/ DirectorySearcher
): Active Directory:更好的性能
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.