首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> C# 入門

活動目錄 (AD) .NET 開發實戰技巧總匯:從基礎概念到高效查詢

     編輯:C# 入門

核心概念速查

術語全名說明
ADsPathActive Directory Service Path物件唯一路徑,格式 LDAP://DC=domain,DC=com 或 LDAP://Server/DC=domain,DC=com
DNDistinguished Name完整唯一名稱,如 CN=Admin,CN=Users,DC=domain,DC=com
RDNRelative Distinguished Name相對父容器的名稱,如 CN=Admin
CNCommon Name通用名稱 (使用者、群組、電腦等)
OUOrganizational Unit組織單元 (容器),可委派管理權限
DCDomain Component網域元件 (DNS 網域名稱拆解)
GUIDGlobally Unique Identifier物件不變的唯一識別碼 (跨網域移動不變)
SIDSecurity Identifier安全性主體識別碼 (權限核心)

三大命名內容 (Naming Contexts)

  • Domain NC:DC=domain,DC=com - 使用者、群組、電腦、OU 等業務資料。
  • Configuration NC:CN=Configuration,DC=domain,DC=com - 網站、子網、複寫拓撲、信任關係等基礎建設設定。
  • Schema NC:CN=Schema,CN=Configuration,DC=domain,DC=com - 類別與屬性定義 (可擴充)。

System.DirectoryServices 核心類別

DirectoryEntry - 物件操作

using System.DirectoryServices;

// 綁定 (支援指定認證)
var entry = new DirectoryEntry("LDAP://DC=domain,DC=com", "user", "pwd", AuthenticationTypes.Secure);

// 常用操作
entry.Properties["description"].Value = "更新說明";
entry.CommitChanges(); // 寫回 AD

// 建立子物件
var newUser = entry.Children.Add("CN=NewUser", "user");
newUser.Properties["sAMAccountName"].Value = "newuser";
newUser.CommitChanges();

// 移動/重命名
newUser.MoveTo(new DirectoryEntry("LDAP://OU=TargetOU,DC=domain,DC=com"));

// 列舉子物件
foreach (DirectoryEntry child in entry.Children) {
    Console.WriteLine($"{child.Name} - {child.SchemaClassName}");
}

// 多值屬性處理 (如 memberOf)
foreach (object val in entry.Properties["memberOf"])
    Console.WriteLine(val);

DirectorySearcher - 高效查詢

var searcher = new DirectorySearcher(entry) {
    Filter = "(&(objectCategory=person)(objectClass=user)(mail=*@domain.com))",
    SearchScope = SearchScope.Subtree,
    PageSize = 1000, // 啟用分頁,繞過伺服器 MaxPageSize 限制
    PropertiesToLoad = { "cn", "mail", "department", "manager" }
};

// 異步查詢大量資料
foreach (SearchResult result in searcher.FindAll()) {
    var de = result.GetDirectoryEntry(); // 取得 DirectoryEntry (會再發一次 RPC)
    // 建議直接用 result.Properties 讀取已載入屬性,避免額外往返
    string mail = (string)result.Properties["mail"][0];
}

SearchScope 三種模式圖解

  • Base:僅查詢 SearchRoot 本身。
  • OneLevel:查詢 SearchRoot 直系子物件 (不含孫輩)。
  • Subtree:查詢 SearchRoot 及所有後代 (預設、最常用)。

SQL Server 連結伺服器查詢 AD (OpenQuery)

-- 建立連結伺服器 (一次)
EXEC sp_addlinkedserver 'ADSI', 'Active Directory Service Interfaces', 'ADSDSOObject', 'adsdatasource';

-- 查詢範例
SELECT displayName, mail, telephoneNumber, sAMAccountName
FROM OPENQUERY(ADSI, '
    SELECT displayName, mail, telephoneNumber, sAMAccountName
    FROM ''LDAP://DC=domain,DC=com''
    WHERE objectClass = ''user'' AND objectCategory = ''person''
')
WHERE mail LIKE '%@domain.com';

ADAM (Active Directory Application Mode) 快速認知

  • 輕量級 LDAP 目錄服務,獨立於作業系統網域,無需 DNS、無網域控制站角色。
  • 單機可跑多個 Instance (每個 App 一個),以使用者模式服務運行 (非系統服務)。
  • 適用場景:應用程式專用目錄、Extranet 身分存放、開發測試環境。
  • .NET 操作方式同 AD,僅綁定路徑改為 LDAP://localhost:389/CN=Partition,CN=Schema,CN=Configuration 等。

效能調優關鍵清單

  1. **指定 PropertiesToLoad** 只取需要屬性,減少網路傳輸。
  2. **設定 PageSize** (如 1000) 啟用分頁,避免單次回傳過大被截斷。
  3. **使用索引屬性查詢** (如 `sAMAccountName`, `objectGUID`, `mail`),避免全樹掃描。
  4. **重用 DirectoryEntry/Searcher** 物件,減少綁定開銷。
  5. **批次修改** 使用 `DirectoryAttributeModification` 合併多屬性一次 Commit。
  6. **GC (Global Catalog) 查詢** 跨網域搜尋時連接 GC Port 3268,單一查詢覆蓋整個林。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved