İçindekilerGirişİndex
YukarıİlkÖncekiSonraki YokSon
Geriİleri
Yazdır
Onder Teker
on_der_tek_er@yahoo.com

.NET'te Directory Services'le Programlama

LDAP

.NET'te directory service'leri için System.DirectoryServices namespace'i adı altında bir library bulunmaktadır. Bununla Active Directory service'lerine bağlanılabilir. LDAP protokolü kullanılarak bir directory server'a erişmek oldukça kolaydır.

LDAP URL'i

Diyelim ki server'da aşağıdaki gibi dizin yapısı var

o=MyCompany
	ou=Members
		cn=mahmut

Bu nesneye erişim için yazılması gereken URL

LDAP://ldap.mycompany.com:4321/o=MyCompany/ou=Members/cn=mahmut

şeklinde olmalıdır. Burada 'LDAP' ifadesi protokolü, 'ldap.mynet.com' server'ın hostname'ini 4321 de servisin çalıştığı port numarasını belirtir. Bu URL'e karşılık gelen entry'nin gerçekten de belirtilen server'da bulunup bulunmadığını anlayan bir kod yazalım :

string url="LDAP://ldap.mycompany.com:4321/o=MyCompany/ou=Members/cn=mahmut";
bool exists=DirectoryEntry.Exists(url);
Console.WriteLine("Directory Exists? : "+exists);

Burada Exist() methodu, DirectoryEntry class'ının bir entry'nin var olup olmadığını öğrenmeye yarayan static bir üyesidir.

ATTRIBUTE'LER

LDAP'ta her entry çeşitli attributeler içerebilir. Bir entry'deki 'sn' (surname) adlı atribute'yi alan bir kod parçası yazalım :

string url="LDAP://ldap.mycompany.com:4321/o=MyCompany/ou=Members/cn=mahmut";
DirectoryEntry entry=new DirectoryEntry(url);
string attribute=(string)entry.Properties["sn"].Value;
Console.WriteLine("Attribute Value : "+attribute);

burada DirectoryEntry class'ının 'Properties' property'sinin içinde 'sn' key'ine karşılık gelen değeri almaktayız. Bütün attributeleri alan bir kod yazalım.

string url="LDAP://ldap.mycompany.com:4321/o=MyCompany/ou=Members/cn=mahmut";
DirectoryEntry entry=new DirectoryEntry(url);
IEnumerator e=entry.Properties.PropertyNames.GetEnumerator();
while(e.MoveNext()){
	string id=(string)e.Current;
	Console.WriteLine(id+" : "+entry.Properties[id].Value);				
}

ENTRY İŞLEMLERİ

Bir directory'nin altına başka bir directory eklemek için aşıdaki gibi bir kod yazılabilir

string parentUrl="LDAP://ldap.mycompany.com:4321/o=MyCompany/ou=Members";
DirectoryEntry parent=new DirectoryEntry(parentUrl);
DirectoryEntry child=parent.Children.Add("cn=xyz123","member");
child.Properties["sn"].Value="asfsa";
child.CommitChanges();

Bir directory bir üst directory'ye eklenebilir. Tek başına yaratılamaz.

Yapılan değişiklikler CommitChanges() dedikten sonra server'a kaydedilir. Bu method çağırılmazsa değişiklikler hafızada kalır.

Aynı şekilde silmek de

DirectoryEntry dead=parent.Children.Find("cn=xyz123");
parent.Children.Remove(dead);

biçiminde bir kod yazılabilir. Bir entry'nin property'lerini update etmek için

DirectoryEntry dead=parent.Children.Find("cn=xyz123");
child.Properties["sn"].Value="Atmaca";
child.CommitChanges(); 

biçiminde önce bulunmalı, sonra değişiklik commit edilmelidir.

SCHEMA

Class Schema'sı, bir directory entry'sinde bulunabilecek ve buluması gereken attributeleri belirtir. Attribute Schema'sı da bir attributenin alabileceği değeri tipi ve sayısını gösterir. (LDAP'ta bir attribute birden fazla değer alabilir.) Bir entry yaratılırken mutlaka Class Schema'sı belirtilmelidir. Schema'da olmayan bir attribute girilirse veya schema'da bulunması zorunlu attribute girilmeden entry yaratılmaya çalışılırsa hata gelir. LDAP server'larda tanımlanmış, bütün dünyanda yaygın olarak kullanılan bir çok class ve attribute bulunmaktadır.

Class Schema, bir attribute setidir ve bir directory entry'sinin birden fazla scheması bulunabilir. Bu şekilde birden fazla directory'de ortak kullanılan attribute'ler bir schema'da tanımlanır ve diğerelerinde tekrar tekrarlanmak zorunda kalınmaz.

Yukarıdaki örneklerin çalışması için System.DirectroyService'in referans olarak eklenmesi ve using'le belirtilmesi gerekir.

SEARCH

Bir directory'nin altındaki entry'ler arasında filtreler kullanarak search yapılabilir. Örenğin 'sn' (soyadı attributesi) Alkan alan kişilerin sayısını öğrenmek için

string rootUrl="LDAP://ldap.mycompany.com:4321/o=MyCompany/ou=Members";
DirectoryEntry top=new DirectoryEntry(rootUrl);
DirectorySearcher searcher=new DirectorySearcher(top);
searcher.Filter = "(sn=alkan)";
SearchResultCollection results = searcher.FindAll();
Console.WriteLine(" results.Count : "+results.Count);

şeklidne bir sorgu yapılabilir. Bir sorgunun sonuçlarını, yani sonuç olarak dönen attribute'leri elde edmek için

foreach (SearchResult result in results) {
	foreach (string key in result.Properties.PropertyNames) {
		Console.Write(key+ " : ");
		foreach (object values in result.Properties[key]) {
			Console.Write(values);
		}
		Console.WriteLine();
	}
}

şeklinde bir kod yazılır. Sonuç (SearchResult) da bir directory entry gibi attributeler içerir. İç içie iki döngü yapmamızın nedeni, bir attributenin birden fazla değer döndürme ihtimalinin olmasıdır. Aksi belirtilmedikçe filtre'de belirtilen kiritelere uyan entry'lerin bütün attribute'leri döner. Sadece belli attributeleri almak için

searcher.PropertiesToLoad.Add("givenName");
searcher.PropertiesToLoad.Add("postalAddress");

şeklinde bir ekleme yapmak gereklidir. Filtre LDAP filtrelerinin belirlediği sözdizimine uymalıdır.

"(&(sn=alkan)(givenName=remzi)":	hem sn'i alkan olan hem de givenName'i remzi olanlar
"(al*)                         :	'al'la başlayanlar

İstenirse search için scope, yani 'derinlik' verilebilir. 'Base' denirse search tek bir kök nesne üzerinde olabilir ve sonuçta sadece bir nesne olur. 'OneLevel' değeri, search'ün bir nesnenin hemen altındaki nesnelerde yapılacağını. SubTree is bir nesnenin kendisi, hemen altındakiler, onlarında altıntakiler şeklinde en aşağıya kadar sorgu yapmak için kullanılır. Scope belirmek için

searcher.SearchScope=SearchScope.OneLevel;

şeklinde bir ifade girilmelidir.

İçindekilerGirişİndex
YukarıİlkÖncekiSonraki YokSon
Geriİleri
Yazdır