简体   繁体   English

从 Principal 而不是 DirectorySearcher 的 SearchResult 获取额外的 Active Directory 属性

[英]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.

相关问题 如何在.NET中获取DirectorySearcher的SearchResult的DN? - How to get DN for a DirectorySearcher's SearchResult in .NET? AccountManagement.Principal的Active Directory底层搜索者组属性 - Active Directory Underlying Searcher Group Attributes from AccountManagement.Principal 使用C#从Active Directory中从DirectorySearcher获取子对象属性的最有效方法 - Most efficient way to get child object properties from a DirectorySearcher result in Active Directory using C# 从Outlook.MailItem获取发件人活动目录用户主体 - Get the senders active directory user principal from Outlook.MailItem Active Directory DirectorySearcher未返回所有可用属性 - Active Directory DirectorySearcher is not returning all of the available properties Active Directory:无法使用DirectorySearcher与服务器联系 - Active Directory: The server could not be contacted using DirectorySearcher 如何通过诸如Department之类的属性从Active Directory获取用户列表 - How to get list of Users from Active Directory by attributes such as Department 如何从 C# 中的 Active Directory 用户获取所有属性 - How to get All attributes from an Active Directory user in C# 我可以从WindowsPrincipal获取Active Directory属性吗? - Can I get Active Directory attributes from the WindowsPrincipal? 对SearchResult集合进行部分搜索-Active Directory,所有组 - Partial Search on SearchResult collection - Active Directory, all Groups
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM