Làm việc với Active Directory - Lập trình Active Directory - Phần 3
Tạo ra các đối tượng mới
Muốn tạo ra các đối tượng mới trong Active Directory như
user,computer,printer,contact . ta có thể dùng lớp DirectoryEntry
để thêm 1 đối tượng mới đến thư mục ta phải kết nối đến 1 đối tượng
chứa,ví dụ như là OU .ở đây ta dùng đối tượng chứa với tên phân biệt
CN=Users, DC=eichkogelstrasse, DC=local:
DirectoryEntry de = new DirectoryEntry();
de.Path = "LDAP://celticrain/CN=Users, DC=eichkogelstrasse, DC=local";
Ta có thể lấy đối tượng DirectoryEntries bằng thuộc tính Children của
DirectoryEntry :
DirectoryEntries users = de.Children;
Với DirectroyEntries ta có phương thức thêm ,bỏ ,tìm các đối tượng trong
tập.ở đây ta tạo đối tượng user mới bằng phương thức Add(),ta cần tên của
đối tượng và kiểu. ta có thể lấy tên kiểu trực tiếp dùng ADSI Edit:
DirectoryEntry user = users.Add("CN=John Doe", "user");
st": user.Properties["company"].Add("Some Company"); user.Properties["department"].Add("Sales"); user.Properties["employeeID"].Add("4711"); user.Properties["samAccountName"].Add("JDoe"); user.Properties["userPrincipalName"].Active Directoryd("JDoe@eichkogelstrasse.local"); user.Properties["givenName"].Add("John"); user.Properties["sn"].Add("Doe"); user.Properties["userPassword"].Add("someSecret"); Cuối cùng ta viết dữ liệu đến Active Directory, ta phải flush cache : user.CommitChanges(); Cập nhật các mục trong thư mục Sau khi đọc đối tượng ta có thể thay đổi giá trị . để bỏ tất cả các giá trị của 1 thuộc tính đơn ta gọi phương thức PropertyValueCollection.Clear() .dùng Add() để thêm giá trị mới đến thuộc tính.dùng Remove() và Removeat() để bỏ các giá trị đặc tả từ 1 tập thuộc tính Ta thay đổi 1 giá trị đơn giản bằng các thiết lập nó đến một giá trị đặc tả.ví dụ sau cho thấy số điện thoại được thay đổi và dùng 1 indexer trong PropertyValueCollection.với indexer 1 giá trị chỉ có thể thay đổi nếu tồn tại.do đó ta nên luôn kiểm tra DirectoryEntry.Properties.Contains() nếu thuộc tính có trá trị : using (DirectoryEntry de = new DirectoryEntry()) { de.Path = "LDAP://celticrain/CN=Christian Nagel, " + "OU=Wrox Press, DC=eichkogelstrasse, DC=local"; if (de.Properties.Contains("mobile")) { de.Properties["mobile"][0] = "+43(664)3434343434"; } else { de.Properties["mobile"].Add("+43(664)3434343434"); } de.CommitChanges(); } Trong phần else ta thêm 1 thuộc tính mới có số điện thoại nếu nó không tồn tại bằng phương thức PropertyValueCollection.Add(). nếu ta dùng Add() với 1 thuộc tính tồn tại kết quả tuỳ thuộc vào kiểu của thuộc tính - đơn hay đa giá trị. nếu là thuộc tính có giá trị đơn sẽ xảy ra biệt lệ : COMException: A constraint violation occurred. nếu là đa giá trị thì chấp nhận xem như là đó là giá trị thêm. Vì thuộc tính của điện thoại là đơn giá trị nên không thể thêm vào . tuy nhiên người dùng có thể có nhiều số điện thoại. nếu ta thiết lập thuộc tính otherMobile. otherMobile là đa giá trị thì ta có thể gọi Add() nhiều lần.có 1 điểm quan trọng đối với thuộc tính đa giá trị : các giá trị không được giống nhau . nếu giống sẽ sinh ra biệt lệ :COMException: The specified directory service attribute or value alreActive Directoryy exists. Truy xuất các đối tượng ADSI bẩm sinh Lớp DirectoryEntry hổ trợ việc gọi các phương thức của các đối tượng bên dưới trực tiếp bằng cách dùng phương thức Invoke(). Thông số đầu tiên của invoke() là tên phương thức được gọi trong đối tượng ADSI, từ khoá params trong thông số thứ 2 cho phép 1 số các đối số thêm được truyền vào phương thức ADSI: public object Invoke(string methodName, params object[] args); Trong ví dụ sau ta dùng phương thức IADsUser.SetPassword() để thay đổi password của đối tượng user trước đã tạo : using (DirectoryEntry de = new DirectoryEntry()) { de.Path = "LDAP://celticrain/CN=John Doe, " + "CN=Users, DC=eichkogelstrasse, DC=local"; de.Invoke("SetPassword", "anotherSecret"); de.CommitChanges(); } Thay vì dùng Invoke() ta cũng có thể dùng trực tiếp các đối tượng ADSI bên dưới. để làm điều này ta phải thêm 1 tham chiếu đến Active DS Type Library bằng cách dùng Project|Add reference. sẽ tạo ra một lớp gói ( wrapper) trong lớp này ta có thể truy xuất các đối tượng ADSI trong namespace ActiveDs. Các đối tượng bẩm sinh có thể đưọc truy xuất bằng thuộc tính NativeObject của lớp DirectoryEntry . ví dụ , đối tượng de là 1 đối tượng user,vì thế ta có thể ép kiểu nó thành ActiveDs.IADsUser. SetPassword() . bằng cách thiết lập thuộc tính AccountDisabled là false ta có thể cho phép account. ActiveDs.IADsUser user = (ActiveDs.IADsUser)de.NativeObject; user.SetPassword("someSecret"); user.AccountDisabled = false; de.CommitChanges(); Tìm kiếm trong Active Directory Để tìm kiếm trong Active Directory, .NET framework có lớp DirectorySearcher .ta chỉ có thể dùng DirectorySearcher với provider LDAP ,nó không làm việc với các provider khác như NDS hoặc IIS Trong hàm dựng của lớp DirectorySearcher ta có thể định nghĩa 4 phần quan trọng cho việc tìm kiếm - SearchRoot : gốc tìm kiếm đặc tả nơi bắt đầu tìm kiếm .mặc định là gốc của domain đương thời. SearchRoot đưọc đặc tả với path của đối tượng DirectoryEntry - Filter :Filter định nghĩa các giá trị mà ta muốn lấy .filter là 1 chuỗi phải nằm trong dấu ngoặc đơn. Các tác tử quan hệ như = được dùng trong biểu thức ví dụ (objectClass=contact) sẽ tìm tất cả các đối tượng có kiểu contact;(lastName>=Nagel) tìm tất cả các đối tượng có lastname lớn hơn hoặc bằng Nagel ( tìm theo Alphabet) biểu thức có thể kết hợp với tác tử tiền tố & và | . ví dụ : (&(objectClass=user)(description=Auth*)) tìm tất cả các đối tượng kiểu user có thuộc tính description bắt đầu bằng Auth. vì tác tử & và | nằm ở đầu biểu htức nên có thể kết hợp nhiều hơn 2 biểu thức với 1 tác tử tiền tố đơn. filter mặc định là (objectClass=*) - PropertiesToLoad : với PropertiesToLoad ta định nghĩa 1 StringCollection của tất cả các thuộc tính mà ta quan tâm . các đối tượng có thể có nhiều thuộc tính , hầu hết là không quan trọng trong yêu cầu tìm kiếm của ta.ta định nghĩa các thuộc tính mà sẽ đưọc load vào cache. ta sẽ lấy thuộc tính mặc định nếu Path và Name của đối tượng không được đặc tả. - SearchScope : SearchScope là 1 bảng liệt kê định nghĩa độ sâu của việc tìm kiếm : + SearchScope.Base chỉ tìm các thuộc tính trong đối tượng nơi việc tìm bắt đầu . với SearchScope.OneLevel việc tìm kiếm tiếp tục trong tập con của đối tượng cơ sở . + SearchScope.Subtree định nghĩa việc tìm kiếm sẽ tìm toàn bộ cây Mặc định SearchScope là Subtree Giới hạn tìm kiếm Việc tìm kiếm có thể trải rộng trên nhiều domain. để giới hạn tìm kiếm hay thời gian tìm kiếm ta có thể định nghĩa một số thuộc tính sau : - ClientTimeout : thời gian lớn nhất mà client chờ server trả về kết quả - PageSize : với 1 page search server trả về 1 số đối tượng đưọc định nghĩa với Pagesize thay cho kết quả hoàn chỉnh.điều này rút gọn thời gian client nhận lần trả lời đầu và bộ nhớ cần thiết.server gửi cookies đến client ,mà sẽ gửi trả lại server lần phản hồi tìm kiếm lần tiếp theo, để tìm kiếm có thể tiếp tục ở thời điểm nó đã hoàn thành - ServerPageTimeLimit : giá trị này định nghĩa thời gian 1 cuộc tìm kiếm nên tiếp tục để trả lại số đối tượng mà được định nghĩa với giá trị pagesize.mặc định là -1, nghĩa là không xác định - ServerTimeLimit : định nghĩa thời gian lớn nhất server sẽ tìm các đối tượng. khi hết thời gian, các đối tượng được tìm thấy đến thời điểm này sẽ được trả về cho client.mặc định là 120 giây, ta không thể thiết lập giá trị cao hơn. - ReferalChasing : nếu gốc tìm được đặc tả thông qua SearchRoot là domain cha hay không đặc tả gốc ,việc tìm kiếm có thể tiếp tục ở các domain con. với thuộc tính này ta có thể đặc tả việc tìm kiếm trên các server khác. ReferalChasingOption.None : không tìm kiếm trên các server khác. ReferalchasingOption.Subordinate : đặc tả tìm kiếm tiếp tục trên các domain con. khi tìm ở DC=Wrox, DC=COM server có thể trả về tập kết quả và tham chiếu đến DC=France,DC=Wrox,DC=COM. ReferalchasingOption.External: server có thể chuyển client đến 1 server độc lập không nằm trong các domain con.đây là tuỳ chọn mặc định. ReferalchasingOption.All thì cả tham chiếu external và subordinate đều được trả về. Ví dụ ta muốn tìm kiếm tất cả các đối tượng user trong Wrox Press, thuộc tính Description có giá trị của Author đầu tiên ta kết nối với Wrox Press.đây là nơi bắt đầu tìm kiếm .ta tạo ra đối tượng DirectorySearcher . Filter được định nghĩa (&(objectClass=user)(description=Auth*)), để tìm các đối tượng user với description bắt đầu bằng Auth. phạm vi tìm kiếm là các cây con, để các tổ chức con trong Wrox Press cũng được tìm kiếm: using (DirectoryEntry de = new DirectoryEntry("LDAP://OU=Wrox Press, DC=eichkogelstrasse, DC=local")) using (DirectorySearcher searcher = new DirectorySearcher()) { searcher.SearchRoot = de; searcher.Filter = "(&(objectClass=user)(description=Auth*))"; searcher.SearchScope = SearchScope.Subtree; Các thuộc tính ta muốn có trong tập kết quả là name,description ,givenName,wWWHomePage: searcher.PropertiesToLoActive Directory.Add("name"); searcher.PropertiesToLoActive Directory.Add("description"); searcher.PropertiesToLoActive Directory.Add("givenName"); searcher.PropertiesToLoActive Directory.Add("wWWHomePage"); Để sắp sếp kết quả ta dùng thuộc tính sort của DirectorySearcher ta có thể thiết lập 1 sortoption . đối số đầu tiên là thuộc tính muốn sắp xếp,thứ hai là cách sắp xếp.bao gồm Ascending và Descending Để bắt đầu tìm kiếm ta dùng phương thức FindOne() để tìm đối tượng đầu tiên hoặc là FindAll().FindOne() trả về SearchResult trong khi FineAll() trả về SearchResultCollection. ta muốn lấy tất cả các tác giả , nên ta dùng FindAll(): searcher.Sort = new SortOption("givenName", SortDirection.Ascending); SearchResultCollection results = searcher.FindAll(); Ta có thể dùng vòng lặp foreach duyệt qua các đối tượng SearchResult trong SearchResultCollection . mỗi searchReuslt là 1 đối tượng trong cache tìm kiếm. thuộc tính properties trả về 1 ResultPropertyCollection ,nơi ta truy xuất tất cả các thuộc tính và giá trị với tên thuộc tính và indexer: SearchResultCollection results = searcher.FindAll(); foreach (SearchResult result in results) { ResultPropertyCollection props = result.Properties; foreach (string propName in props.PropertyNames) { Console.Write(propName + ": "); Console.WriteLine(props[propName][0]); } Console.WriteLine(); } } Nếu ta muốn lấy các đối tượng hoàn chỉnh sau khi tìm kiếm ta dùng phương thức getdirectoryEntry() của SearchResult mà trả về DirectoryEntry của đối tượng.
File đính kèm:
- Active_Directory_3 .pdf