.NET içinde Active Directory işlemleri

.NET destekli programlama dillerini kullanarak Active Directory(AD) üzerinde sorgulamalar yapabiliriz. Bu amaçla .NET Framework, System.DirectoryServices kütüphanesini sunar. Bu kütüphanenin sınıflarını kullanarak, AD üzerinde sorgulamalar yapılabilir, ilgili nesnelere ulaşılabilir, kullanıcıların authentication işlemi sağlanabilir, web/windows/console uygulamalarından AD kayıt güncellemeleri gerçekleştirilebilir. DirectoryServices kütüphanesinin sınıflarına geçmeden önce AD’nin desteklediği LDAP standartından bahsedelim.

LDAP (Lightweight Directory Access Protocol),TCP/IP üzerinde çalışan dizin servislerini sorgulamak ve düzeltmek için kullanılan bir ağ iletişim kuralıdır. Bir dizin mantıksal ve sıralı olarak düzenlenmiş benzer özellikteki bilgiler topluluğudur.Dizine en yaygın örnek telefon rehberidir.Bir telefon rehberinde kişiler veye kurumlar alfabetik olarak dizilmiş isimler ile adresler ve telefon numaralarından oluşur. LDAP özellikle kurum içi personelin kayıtlarının tutulabileceği elverişli bir ortam sunar. Bir kurumda çalışanlara çeşitli servisler sunmanız gerekir. Bunun için her servisin üzerinde çalıştığı makinada ayrı ayrı kullanıcı hesapları açmanız gerekebilir. LDAP kullanarak bu sorun çözülebilir.Kuruma giren personel için LDAP sunucusuna tek bir giriş eklersiniz ve LDAP desteği veren servislerin bu sunucu üzerinden kullanıcı bilgilerine erişim ve doğrulama yapmalarını sağlayabilirsiniz. LDAP, Tcp Port’larından 389’u kullanır, blindrequest, addrequest, delrequest, modifyrequest vs. komutları olan bir iletişim kuralıdır. LDAP; Microsoft ve diğer işletim sistemlerinde Active Directory ile sorunsuz çalışan bir iletişim kuralıdır.
LDAP hiyerarşik yapıda ayrıntılı olarak nitelik bilgilerinin tutulduğu ve genellikle okuma hakkı ile erişilen veri tabanıdır. Bu veri tabanı içerisinde tutulan bilgiler; gruplar, nesneler, nesne sınıfları, kişi, grup, organizasyon nesne gruplarına ait isim, soyisim, e-posta adresi, tel, kullanıcı ev dizini gibi alt bilgilerdir. Aslında Active Directory de LDAP yapısı üzerinde çalışmakla birlikte Unix/Linux sistemlerinde çalışan LDAP ile uyumlu değildir. Değişik LDAP servisi veren yazılımlar olmasına rağmen, açık kaynak kodlu Open LDAP servisi yazılımına http://www.openldap.org adresinden erişilip kurulumu ve yapılandırması gerçekleştirilebilir. Belirtilen site adresinde ve değişik pek çok yerde yazılımla ilgili bol miktarda ayrıntılı belge mevcuttur.

LDAP, tam olarak bir database mimarisine sahip olmasa da hiyerarşik düzende bir database yapısına yakın olduğu için sorgulanması ve üzerinde işlem yapılması kolaydır. LDAP servisi kullanılarak, kullanıcı adı ve şifre ikilisiyle merkez sistemden yetki alınarak merkez sistem üzerindeki nesnelere, sistem bilgilerine, diğer kullanıcılara, domainde olan makinelere erişilebilir.
System.DirectoryServices namespace, AD servisiyle ilgili birçok sınıf içerir. Bunlardan en çok kullanılan iki temel sınıf; DirectoryEntry ve DirectorySearcher classlarıdır. DirectoryEntry sınıfı, Active Directory hiyerarşisindeki bir node veya nesneyi erişmemizi sağlar. Bu sınıfın overlaod edilmiş constructörü, genellikle ulaşılacak merkez sistem adresini, kullanıcı adı ve şifre parametrelerini aldığı versiyonuyla kullanılır. DirectorySearcher sınıfı, Active Directory üzerinde çalışacak sorgulamayı hazırlar. AD’nin bulunduğu merkezi sistemin pathini LDAP standartına göre veriyoruz. Yani LDAP://SunucuAdi/HiyerarsidekiNodeAdi şeklinde uzaktaki sunucuyu işaret edebiliriz. Bu yazıda, örneklerle .NET Framework’ün ilgili sınıf ve üyelerini işleyeceğiz.

//AD'ye bağlan
DirectoryEntry objDe = new DirectoryEntry("LDAP://
 Bulunduğumuz nodetaki tüm propertylere ve değerlerine erişmek için iç içe bir döngü oluşturmak gerekir. Aşağıdaki kod yardımıyla bu hiyerarşik yapıyı yazdırabiliriz.
PropertyCollection Pc = objDe.Properties;
foreach (string prName in Pc.PropertyNames)
{
  foreach (object value in objDe.Properties[prName])
    Response.Write("property = "+ prName +"   value ="+ value );
}

Active Direcory üzerindeki nesneleri sorgulamak için DirectorySearcher sınıfı kullanılır. Bu sınıfın Filter propertysinde LDAP Search Filter Syntax’ına uygun ifadeler girilerek kayıtlara erişebiliriz.RFC2254 standartına göre kullanılan LDAP arama ifadelerinden bazıları şunlardır;

Arama filtresi Açıklama
“(objectClass=*)” All objects.
“(&(objectCategory=person)(objectClass=user)(!cn=andy))” “andy” dışındaki tüm userlar
“(sn=sm*)” surname niteliği “sm” ile başlayan nesneler
“(&(objectCategory=person)(objectClass=contact)(|(sn=Smith)(sn=Johnson)))” Soyadı, “Smith” veya “Johnson” olan tüm contact userler

Bu ifadelerle ilgili detaylı bilgiyi http://msdn2.microsoft.com/en-us/library/aa746475.aspx adresinde bulabilirsiniz.
Sunucu üzerinde tanımlı makineleri listeyelim. Bunun için AD üzerindeki Computer nesnesini sorgulayacağız.

DirectorySearcher ObjSrch = new DirectorySearcher(objDe);
ObjSrch.Filter = "(objectClass=Computer)";

StringBuilder objStr = new StringBuilder();

foreach (SearchResult Srch in ObjSrch.FindAll())
{
    objStr.Append(Srch.GetDirectoryEntry().Name.ToString());
}

Response.Write(objStr.ToString());

Sorgulanan bilgileri sıralamak için SortOption sınıfı kullanılır. Kayıtların tüm propertylerini değil de belirli propertylerini getirmek için PropertiesToLoad property kullanılır. Şu şekilde bir sorgulama yapalım. Firma.Com.Tr isimli sunucu üzerindeki Merkez isimli node altındaki IT düğümünü sorgulayalım. Bu düğümde Adı, “Ahmet” olan kişilerin mail ve telefon bilgilerini getirelim. Bunu da e-mail adresline göre A’dan Z’ye doğru sıralayalım.
//Konumlanacağımız klasörün pathini verelim.
DirectoryEntry objDe = new DirectoryEntry(“LDAP://Firma/OU=IT,OU=Merkez,DC=Com,DC=Tr”,”
Aynı mantıkla DirectoryEntry sınıfının CommitChanges metodu kullanılarak property değerleri üzerinde modify işlemleri yapılabilir.
Uygulamalarımıza giriş yaptırırken kullanıcıların doğrudan AD üzerindeki bilgilerle login olmasını sağlayabiliriz. Böylece şirket içerisindeki personel her uygulama için şifre oluşturmak zorunda kalmaz. Aynı güvenlik bilgileriyle hem makinesine logon olur hem maillerini OWA üzerinden okur hem de uygulamamıza giriş yapmış olur. Bu işlemleri yapmak için özel birşey yapmamıza gerek yok. Yukarıda DirectoryEntry nesnesini tanımladığımız satırda kullanıcının girmiş olduğu bilgilerle AD’ye giriş yapmaya çalışırız dönecek değere göre kullanıcıyı içeri alır veya almayız. Kullanıcı adı veya şifre yanlış olduğu zaman AD’den aşağıdaki hata mesajı döner.Logon failure: unknown user name or bad password.
Active Direcory ile ilgili işlemleri yapmak için projemize System.DirectoryServices kütüphanesini ekleyemi unutmamalıyız.

.NET içinde Active Directory işlemleri” üzerine 34 düşünce

  1. Umut YILMAZ

    Çok aydınlatıcı bir yazı olmuş, benim de gerçekten çok işime yaradı. Türkçe olması da ayrıca çok önemli.Teşekkürler.

    Cevapla
  2. atilla

    merhabalar ben yazmış olduğum kodda şu hatayı alıyorum b konuda bana yardım edebilir misiniz “System.DirectoryServices.DirectoryServicesCOMException: Sunucudan bir başvuru döndürüldü”.hatanın geldiği kod parçacığı ise
    string rootDN = (string)(rootDSE.Properties[“defaultNamingContext”].Value);
    burada yukarıdaki hatayı veriyor nedeni nedir hocam ?

    Cevapla
  3. Ahmet Kaymaz Yazar

    A referral was returned from the server hatası belirgin bir hata olduğu için tüm kodları görmeden birşey diyemeyeceğim ancak sorgulanan verilerle sorguyu yapan kullanıcının aynı domain olmaması veya birden fazla domaini sorguluyor olmak veya DirectoryEntry olmadan arama yapmak bu hataya neden olabilir. DirectoryEntry içerisindeki pathi dinamik oluşturmak yerine doğrudan Domain’in direk rootunu gösteren pathini yazarak denemek hatayı düzeltebilir.

    Cevapla
  4. Fatih

    Merhaba,
    Öncelikle teşekkür ederim böyle bir bilgiyi bizlerle paylaştığınız için.Bir sorum olucaktı benim yaptığınız örneği aynı ağ içinde iken server ımın IP sini yazarak erişebiliyorum fakat farklı ağda olduğumuz zaman server a mı erişemiyorum.İç ağda iken mesela 192.168.2.200 diyip domain name kısmını bağlanıyorum dış ağda iken bizim ulaşmak istediğim server ın çıkış IP sini yazıyorum ama ulaşamıyo tabi kullanıcı adı şifre giriyorum dışardan erişmek için ne yapmak gerekiyor acaba.TESEKKURLER

    Cevapla
  5. Ahmet Kaymaz Yazar

    Merhaba Fatih,AD’nizin dışarıdan erişilebilir olması gerekir. Bu konuda sistem yöneticiniz sizin yönlendirebilir diye düşünüyorum. .NET üzerinden erişmeden önce piyasadaki LDAP Browser, LDAP Administrator gibi programları kullanarak uzaktan erişmeyi denemende fayda vardır.

    Cevapla
  6. Fatih

    Çok teşekkür ederim ama benim .net üzerinden erişmem gerek.ldap browser ile denedim ama yine ulaşamadım sistem lerle ilgilenen arkadaşda benim gibi yeni başladı bu işlere server da yapılması gereken ayarlar varmı benim dışardan erişmem için.içerden erişmek için
    path=”ldap://192.168.2.100¨,”user”,”sifre” yaziyorum erişiyorum ama dışarıdan
    path=”ldap://CıkısIP”,”user”,”sifre” yazıyorum olmuyo bu konu hakkında bilginiz varsa çok minnettar kalırız.TESEKKURLER

    Cevapla
  7. Ahmet Kaymaz Yazar

    Global Catalog ve LDAP sorguları için 389 ve 3268 portlarını dışarıya açık olması gerekir. Yani sunucunuzun LDAP için gerekli olan portlarını dışarıya açmanız gerekiyor ki oradan sorgulama yapabilesiniz. Ama bunun da beraberinde ciddi güvenlik riski meydana getireceğini unutmamalısınız. Aşağıdaki sitedeki ilgili port ve güvenlik durumlarını görebilirsin.http://technet.microsoft.com/en-us/library/cc978012.aspx

    Cevapla
  8. Fatih

    Çok Teşekkür ederim 3268 portunu açınca istediğimiz oldu tabi güvenli olup olmayacağına iyice araştırmak gerekiyor.LDAP://CıkısIP:3268 diye belirtince path kısmına oldu.Kolay GelsinTEŞEKKÜRLER

    Cevapla
  9. onur

    Aynı güvenlik bilgileriyle hem makinesine logon olur hem maillerini OWA üzerinden okur hem de uygulamamıza giriş yapmış olur. Bu işlemleri yapmak için özel birşey yapmamıza gerek yok. Yukarıda DirectoryEntry nesnesini tanımladığımız satırda kullanıcının girmiş olduğu bilgilerle AD’ye giriş yapmaya çalışırız dönecek değere göre kullanıcıyı içeri alır veya almayız.
    yazdığınız kısmı kodlayabilir misiniz..tam olarak nasıl yazmamız gerekir.teşekkürler

    Cevapla
  10. Ahmet Kaymaz Yazar

    Bu cümlelerden kastım bunlardan hemen önceki cümledir; “Uygulamalarımıza giriş yaptırırken kullanıcıların doğrudan AD üzerindeki bilgilerle login olmasını sağlayabiliriz. Böylece şirket içerisindeki personel her uygulama için şifre oluşturmak zorunda kalmaz.” Yani hem intranet hem OWA hem de makinesine logon olmak kullanıcı AD üzerinde bir account açmak yeterli olacaktır. Her uygulamaya özgü şifre vermemiş oluruz. Yazıdaki ilk kod alanı, .NET uygulaması içerisinde nasıl AD’de kullanıcı sorgulanacağını içermektedir.

    Cevapla
  11. onur

    Temel problemim bilgisayar şifresini girdiklerinde bunu web sitesindeki koda nasıl entegre edip ona göre id alırım.bu id ye göre kiiye özel vt işlemleri gereçekleştirmeye çalışacam.Yukarıdaki ilk kodla bunu nasıl konuşturabilirim.

    Cevapla
  12. Ahmet Kaymaz Yazar

    Veritabanında User tablosu olacak. Her akşam AD’den kullanıcıları alıp bu tabloya aktaracak bir EXE programı yazacaksın. AD’den gelen kullanıcılar daha önce tabloda mevcut ise birşey yapmayacaksın yoksa INSERT işlemi yapacaksın. Dolayısıyla her kullanıcıya kendi uygulaman tarafında bir ID vermiş olursun.

    Cevapla
  13. Mehmet Y

    Ahmet bey öncelikle örnek için sağolun. Sorum şu;
    Active Directory ile kullanıcın logonhours unu nasıl değiştirebilirim, teşekkürler.

    Cevapla
  14. Ahmet Kaymaz Yazar

    Mehmet Bey,”NET USE” komutu ile aşağıdaki gibi değiştirebilirsin.NET USER USER_NAME /TIMES:MONDAY,TUESDAY,2 Konuyla ilgili detay şu linktedir;http://support.microsoft.com/default.aspx?scid=kb;en-us;179450Aynı şekilde VBScript ile bu işlemi yapmak aşağıdaki dosyada anlatılan komut serisi yardımcı olabilir.http://www.sd61.bc.ca/windows2000/Docs/VBScriptDir.doc.NET’te bu işlemi yapmak için DirectoryEntry.Invoke() ile çağrılabilecek bir yordama denk gelmedim. Aklıma başka bir yöntem gelirse yazarım. Invoke() yordamıyla çağrılabilecek ADSI arabirimleri aşağıdaki adreslerde listelenmiştir;http://msdn.microsoft.com/library/en-us/adsi/adsi/iadsuser.asphttp://msdn.microsoft.com/library/en-us/adsi/adsi/iadsgroup.asphttp://msdn.microsoft.com/library/en-us/sds/sds/list_of_adsi_interfaces_to_invoke.asp

    Cevapla
  15. Mehmet Y

    Ahmet Bey cevabınız için sağolun,
    Net user komutunu .net içinde shell e çağırmayı denemiştim ki bu komutu sadece lokal kullanıcılar için kullanabildim, domaindeki kullanıcılarda kullanamadım, sanırım komutun direkt dc üzerinden kullanılması gerekiyor ama benim kullandığım bilgisayar dc değil sadece domaine dahil Active Directory User and Computers kurulu olduğu bir makina. AD de üzerinden değiştirmeme rağmen net user ile kullanıcı bulunamadı diyor. Teşekkürler

    Cevapla
  16. Murat

    Selamlar
    Bu faydalı yazınız için teşekkür ederim.
    AD ile ilgili bir sorum olacak.
    AD ye ait loglar nerede tutulur ve bu loglara c# ile ulaşmanın bir yolu var mıdır?
    Kolay Gelsin.

    Cevapla
  17. Ahmet Kaymaz Yazar

    Murat,bu konuda uzman sayılmam. AD’nin kendi log dosyalarını (NTDS klasörünün altındaki log, dit dosyası) Microsoft Log Parser ile okuyabilirsin. C# konusunda bir yorum yapamayacağım.

    Cevapla
  18. Berkan

    Selamlar Ahmet Bey, öncelikle çok teşekkür ederim , çok acıklayıcı bir yazı olmuş.Bu konuda size danışmak istediğim bir şey olucaktı , “Kullanıcı adı veya şifre yanlış olduğu zaman AD’den aşağıdaki hata mesajı döner.Logon failure: unknown user name or bad password.” şeklinde açıklamış olduğunuz kısma istinaden , kendi projemdede aynı uyarıyı alıyorum , fakat kullanıcı adı ve şifrem doğru,herzaman kullandığım kullanıcı adı ve şifre.Birde bir keresinde daha farklı bir hata verdi ,
    The server is not operational şeklinde, amacım , login olunması gereken bir uygulamanın, login kısmında , kullanıcının kendi domaindeki kullanıcı adı ve şifresini girdiği an panel’e erişebilmesi.Böyle bir şeyi nasıl tanımlayabilirim , belkide baştan tamamen yanlış yapıyorum , bu konuda yönlendirici bir bilgi verebilirseniz çok sevinirim.Kolay Gelsin, İyi Çalışmalar.

    Cevapla
  19. Ahmet Kaymaz Yazar

    Berkan Bey,eğer o hata mesajı geliyorsa güvenlik bilgileriniz yanlış demektir. Bu bilgilerin doğruluğundan emin olmanız gerekmektedir. Gerekirse domain adını kullanarak kullanıcı adını giriniz. Varsa OWA’ya nasıl giriyorsanız o şekilde yazarsanız olur. Bu proje için doğru seçim yapmışsınız. AD üzerinden giriş yaptıktan sonra paneli açmanız doğru bir işlem.

    Cevapla
  20. TAri

    C# ile active directorydeki computer nesnesine ait bilgileri çekiyorum.Çekitği bilgiler işletim sistemi,ldp ismi,sonb otrum başlama tarihi v.b.Bu bilgisayarların donanımsal bilgilerine(işlemci modeli,anakart markası v.s.) de erişmem lazım.Bunu nasıl yapabilirim.Bu konuda yardımcı olabilirseniz çok sevinirim şimdiden teşekkürler.

    Cevapla
  21. Ahmet Kaymaz Yazar

    Tari,Yerel veya uzaktaki bir makine hakkında bilgi almak için WMI (Windows Management Instrumentation) sorgusu yapılmalıdır. WMI, sisteme ait parçaları izlemek için sunulan Windows bileşenler bütünüdür. .NET tarafında WMI ile çalışmak için System.Management namespace sunulmaktadır. Bununla ilgili bir örnek yapmadım ancak ManagementScope sınıfını kullanarak uzaktaki makineye bağlanılabileceğini ve o şekilde sistem sorgulamalarının yapılabileceğini düşünüyorum.

    Cevapla
  22. TAri

    WMI ile kendi bilgisayarımdaki donanımsal bilgilere erişebiliyorum ancak ManagementScope ile uzaktaki bir makineye bağlanma işini beceremedim maalesef.

    Cevapla
  23. TAri

    Öncelikle cevap için çok teşekkür ederim.İnceledikten ve denedikten sonra sonuçlar hakkında size geri bildirim yapacağım en kısa sürede.

    Cevapla
  24. TAri

    Connection wmiConnection = new Connection(“kullanıcıAdı”,”kullanıcıSifre”,”domainIsmı”,”baglanılmakIstenenBilgisayarIp”); nesnesi bu konuda bana çok yardımcı oldu. Tabi burada kullanılan kullanıcı hesabı admin yetkili bir hesap olmalı.Burada ip scopeunuza göre bir for döngüsü ile ip değerini değişken olarak alıp networkdeki tüm bilgisayarlara ait bilgileri almayı başardım.

    Cevapla
  25. Uğur

    Merhaba Ahmet hocam. Makalenizi okudum hiyerarşik yapıyı yazdırmak istedim ama yapamadım :s//AD’ye bağlan
    DirectoryEntry objDe = new DirectoryEntry(“LDAP://”, “”, “”); bu yazdığınız kod taki sunucu adı “LDAP://denemeldap.com.tr” gibi bişey mi olmalı yoksa “LDAP://denemeldap.com.tr,dc=deneme,dc=aaa” gibi mi olmalı ikisinide denedim olmadı ve bu koddaki kullanıcı ad ve şifre admin kullanıcı adı ve şifresi dimi hocam. Hocam yardımcı olursanız çok sevinirim.

    Cevapla
  26. Ahmet Kaymaz Yazar

    Merhaba Uğur,LDAP adresi olarak LDAP://denemeldap.com.tr,dc=deneme,dc=aaa şeklinde yapman gerekiyor. Eğer bu yol ile erişilemiyorsa bence bir LDAP Browser programı kurup oradan path’i öğrenmende fayda var.

    Cevapla
  27. Uğur

    Hocam teşekkürler . LDAP adresini dediğiniz gibi yazdım ( adreste hata yok çünkü doğrulama entry ekleme gibi işlemleri yapabiliyorum ).hocan şu satırda
    Response.Write(“Sunucu Adı :” + objDe.Name + ” Guid : ” + objDe.Guid);
    şöyle bir hata veriyor
    COMEXception was Unhandled by user code

    Cevapla
  28. Ahmet Kaymaz Yazar

    Uğur,bu çok açıklayıcı bir hata mesajı değil. Genellikle COM uygulamalarında fırlatılan bir mesajdır. Sanırım doğrudan Name veya Guid property’leri kullandıramıyor. Belki Properties[] dizisini kullanabilirsiniz. objDe’nin tüm property’lerini listeyip hangi tanımlamaların olduğunu görebilirsin.

    Cevapla
  29. Bahattin

    Actif Dizin ile entegre çalışan uygulamalar için “dc locator” yöntemi kullanmak istiyoruz ama ben olayı çözemedim.Bu yöntemle uygulamaların içine DC leri statik tanımlamak yerine, uygulamanın DC yi kendisinin bulması sağlanarak, DC lerden biri kapalı iken açık olan DC ile uygulamanın çalışması sağlanmaktadır.Bana bu konu hakkında yardımcı olabilecek var mı ?

    Cevapla
  30. Evren

    Merhaba bir projem var fakat active directory hakkında bir sorum olacak yardımcı olursanız çok sevinirim.

    Active Director üzerinde logon olan kullanıcıların oturumunda çalışan programları listelemek istiyorum.

    c# programla dilinde sorguyu nasıl yapabilirm yardıma ihtiyacım var .

    iyi çalışmlar.

    Cevapla

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Time limit is exhausted. Please reload CAPTCHA.