Yandex Metrica
Active Directory LDAP İle Kullanıcı Kimlik Doğrulama .NET - Yasin Sunmaz

Yasin Sunmaz

Kodladıkça değişen bir dünya...

Active Directory LDAP İle Kullanıcı Kimlik Doğrulama .NET

05.12.2022 yasinsunmaz 2462 0

Active Directory LDAP ile kullanıcıyı belirli bir filtre üzerinde arama veya kullanıcının kimliğini doğrulama işlemleri yapabilmekteyiz. Bu LDAP protokolünde DirectoryServices üzerinden ilgili doğrulama işlemleri yaptım. LDAP tarfındaki işlemleri C# tarafında kod ile yapabilmemiz için form uygulaması hazırladım. İsterseniz GitHub'ta depomu kullanarak form uygulamasında gerekli düzenlemeleri yaparak kolayca kullanabilirsiniz. GitHub Active Directory LDAP deposuna ulaşmak için tıklayın.

Bunun dışında Novell.LDAP kütüphanesi ile de bu işlemleri yapabilmekteyiz. Novell.LDAP kütüphanesinin kullanımını başka bir yazı ve projede yer vereceğim. Novell.LDAP kütüphanesinde kimlik doğrulama ve kullanı aramanın yanı sıra kullanıcı ekleme, silme, güncelleme ve şifre değiştirme gibi farklı işlemleri de yapacağız.

Active Directory LDAP DirectoryServices Form Uygulaması

Mevcut uygulamada sol panelde LDAP admin bilgilerini girerek bağlantı yapıp yapmadığınızı görebilirsiniz. Admin bağlantısını yaptıktan sonra LDAP içerisinde kullanıcı aratabilirsiniz. Eğer bir kullanıcının kimliğini doğrulamak isterseniz o kullanıcın adını ve şifresini girerek şifreyle doğrulama işlemini test edebilirsiniz. LDAP sunucusunda kullanılarak test edilmiştir. Kodda kendi arama filtrelerinizi ve LDAP bilgilerini doğru girmeniz yeterlidir. Sonrasında form uygulamasını kullanarak test edebilirsiniz. Testlerinizden sonra web uygulamanıza kolayca entegre edebilirsiniz.

Active Directory LDAP DirectoryServices Form Uygulaması

LDAP Bağlantısı Gerçekleştirme

LDAP bağlantısı, kullanıcı arama ve kullanıcı kimlik doğrulama işlemleri için form kodları aşağıdaki gibidir.

public partial class DirectoryServicesLDAPForm : Form
  {
    public DirectoryServicesLDAPForm()
    {
      InitializeComponent();
    }

    private System.DirectoryServices.Protocols.LdapConnection _ldapConnectionAdmin;
    private SearchResponse _ldapSearchResponse;
    private string userName;
    private string userDNInfo;

    //LDAP Admin Bağlanma Yönetimi
    private void isAdminConnect_Click(object sender, EventArgs e)
    {
      bool isAdminLdapConnect = isAdminConnectDAP();
      if (isAdminLdapConnect)
      {
        MessageBox.Show("LDAP Bağlantısı Başarılı!");
      }
      else
      {
        MessageBox.Show("LDAP Bağlantısı Başarısız!");
      }
    }

    //LDAP Admin Bağlanma
    private bool isAdminConnectDAP()
    {
      bool status = false;
      string host = txtHost.Text;
      string portValue = comboBoxPort.Text;
      string adminUser = txtAdminUserName.Text;
      string adminPass = txtAdminPassword.Text;
      string ldapSecurityMethod = comboBoxConnectionType.Text;
      bool isDisableCertCheck = chckDisableCertCheck.Checked;

      try
      {
        //LDAP Parametre validasyon kontrolü
        if (isAdminValidation(host, portValue, adminUser, adminPass, ldapSecurityMethod))
        {
          int port = int.Parse(comboBoxPort.Text);
          _ldapConnectionAdmin = new System.DirectoryServices.Protocols.LdapConnection(host + ":" + port);

          NetworkCredential authAdmin = new System.Net.NetworkCredential(adminUser, adminPass);
          _ldapConnectionAdmin.Credential = authAdmin;
          _ldapConnectionAdmin.AuthType = AuthType.Basic;
          _ldapConnectionAdmin.SessionOptions.ProtocolVersion = 3;
          //Port 636 SSL içindir
          if (port == 636)
          {
            ldapProtocolsSecurityMethod(_ldapConnectionAdmin, ldapSecurityMethod, isDisableCertCheck);
          }
          _ldapConnectionAdmin.Bind();
          status = true;
        }
        else
        {
          MessageBox.Show("Tüm bilgiler girilmelidir!");
        }
        return status;
      }
      catch (Exception ex)
      {
        _ldapConnectionAdmin.Dispose();
        txtResult.Text = "Admin LDAP bağlantısı gerçekleşmedi! Mesaj: " + ex.Message;
        return status;
      }
    }

    //Admin Bilgi Validasyon İşlemleri
    private bool isAdminValidation(string host, string port, string adminUser, string adminPass, string ldapSecurityMethod)
    {
      if (host == "" || port == "" || adminUser == "" || adminPass == "" || ldapSecurityMethod == "")
      {
        return false;
      }
      return true;
    }

    //Kullanıcı Arama
    private void isThereAUser_Click(object sender, EventArgs e)
    {
      bool isThereUser = isThereAUserValid();
      if (isThereUser)
      {
        MessageBox.Show("Kullanıcı bulundu!");
      }
      else
      {
        MessageBox.Show("Kullanıcı bulunamadı!");
      }
    }

    //Kullanıcı Arama
    private bool isThereAUserValid()
    {
      bool status = false;
      try
      {
        if (!string.IsNullOrEmpty(txtUserName.Text))
        {
          userName = txtUserName.Text;
          //LDAP aranacak DN bilgisi
          string dn = "dc=abc";

          //LDAP injection saldırılarını önlemek için LDAP arama filtresinden çıkarma
          userName = EscapeLdapSearchFilter(userName);

          System.DirectoryServices.Protocols.SearchRequest ldapSearchRequest;
          ldapSearchRequest = new SearchRequest(dn, string.Format("(&(objectClass=*)(status=active)(|(identity=" + userName + ")(email=" + userName + ")))"), SearchScope.Subtree, null);
          if (_ldapConnectionAdmin != null)
          {
            _ldapSearchResponse = (SearchResponse)_ldapConnectionAdmin.SendRequest(ldapSearchRequest);
            if (_ldapSearchResponse.Entries.Count > 0)
            {
              userDNInfo = _ldapSearchResponse.Entries[0].DistinguishedName;
              //LDAP kullanıcısının detaylı bilgilerini alma - Kullanıcıya ait email bilgisini çekme
              //var attrValue = rsp.Entries[0].Attributes["email"][0].ToString();
              status = true;
            }
          }
          else
          {
            MessageBox.Show("Öncelikle LDAP Bağlantısı Yapmalısınız!");
          }
        }
        else
        {
          MessageBox.Show("Kullanıcı boş geçilemez!");
        }

        return status;
      }
      catch (Exception ex)
      {
        _ldapConnectionAdmin.Dispose();
        txtResult.Text = "Kullanıcı bulunamadı! Mesaj: " + ex.Message;
        return status;
      }
    }

    //Kullanıcı Girişi Doğrulama
    private void isUserLogin_Click(object sender, EventArgs e)
    {
      bool isUserLogin = isUserLoginAuth();
      if (isUserLogin)
      {
        MessageBox.Show("Kullanıcı giriş doğrulandı!");
      }
      else
      {
        MessageBox.Show("Kullanıcı girişi başarısız!");
      }
    }

    //Kullanıcı Giriş Yönetimi
    private bool isUserLoginAuth()
    {
      bool status = false;

      //Mevcut kullanıcı dn  bilgisi varsa direk giriş doğrulama yapılsın
      if (userDNInfo != null)
      {
        return isUserLoginAuthentication();
      }
      else
      {
        //Kullanıcıya ait dn bilgisi yoksa önce kullanıcı var mı bakılıp dn bilgisinin dolması sağlanır
        if (isThereAUserValid())
        {
          //Kullanıcı bulunduktan sonra dn bilgisi doldurulduğu için giriş doğrulama yapılsın
          return isUserLoginAuthentication();
        }
      }
      return status;
    }

    //Kullanıcı Giriş Doğrulama
    private bool isUserLoginAuthentication()
    {
      bool status = false;
      string host = txtHost.Text;
      string portValue = comboBoxPort.Text;
      string ldapSecurityMethod = comboBoxConnectionType.Text;
      bool isDisableCertCheck = chckDisableCertCheck.Checked;
      string userPassword = txtPassword.Text;
      userName = txtUserName.Text;
      if (isUserValidation(host, portValue, userName, userPassword, ldapSecurityMethod))
      {
        int port = int.Parse(comboBoxPort.Text);
        System.DirectoryServices.Protocols.LdapConnection connUserLogin = new System.DirectoryServices.Protocols.LdapConnection(host + ":" + port);
        try
        {
          NetworkCredential auth2 = new System.Net.NetworkCredential(userDNInfo, userPassword);
          connUserLogin.Credential = auth2;
          connUserLogin.AuthType = AuthType.Basic;

          connUserLogin.SessionOptions.ProtocolVersion = 3;

          if (port == 636)
          {
            ldapProtocolsSecurityMethod(connUserLogin, ldapSecurityMethod, isDisableCertCheck);
          }

          connUserLogin.Bind();
          status = true;
          connUserLogin.Dispose();
        }
        catch (Exception ex)
        {
          txtResult.Text = "Kullanıcı giriş doğrulaması başarısız! Mesaj: " + ex.Message;
          connUserLogin.Dispose();
        }
      }
      else
      {
        MessageBox.Show("Host, port, bağlantı şekli, kullanıcı ve şifre alanları girilmelidir!");
      }
      return status;
    }

    //Kullanıcı Giriş Validasyon İşlemleri
    private bool isUserValidation(string host, string port, string userName, string userPassword, string ldapSecurityMethod)
    {
      if (host == "" || port == "" || userName == "" || userPassword == "" || ldapSecurityMethod == "")
      {
        return false;
      }
      return true;
    }

    //SSL 636 Port Bağlantıları
    private static void ldapProtocolsSecurityMethod(System.DirectoryServices.Protocols.LdapConnection _ldapProtocolsConnection, string ldapSecurityMethod, bool isDisableCertCheck)
    {
      if (ldapSecurityMethod == "ssl")
      {
        //SSL doğrulamayı geç
        if (isDisableCertCheck)
        {
          _ldapProtocolsConnection.SessionOptions.VerifyServerCertificate += delegate { return true; };
        }
        _ldapProtocolsConnection.SessionOptions.SecureSocketLayer = true;
      }
      else if (ldapSecurityMethod == "starttls")
      {
        //SSL doğrulamayı geç
        if (isDisableCertCheck)
        {
          _ldapProtocolsConnection.SessionOptions.VerifyServerCertificate += delegate { return true; };
        }
        _ldapProtocolsConnection.SessionOptions.SecureSocketLayer = false;
        _ldapProtocolsConnection.SessionOptions.StartTransportLayerSecurity(null);
      }
    }
/// Escapes the LDAP search filter to prevent LDAP injection attacks.
private static string EscapeLdapSearchFilter(string searchFilter) { 
var escape = new StringBuilder();
      foreach (var current in searchFilter)
      {
        switch (current)
        {
          case '\\':
            escape.Append(@"\5c");
            break;
          case '*':
            escape.Append(@"\2a");
            break;
          case '(':
            escape.Append(@"\28");
            break;
          case ')':
            escape.Append(@"\29");
            break;
          case '\u0000':
            escape.Append(@"\00");
            break;
          case '/':
            escape.Append(@"\2f");
            break;
          default:
            escape.Append(current);
            break;
        }
      }
      return escape.ToString();
}
}

Umarım faydalı olmuştur. İyi çalışmalar.

  • Yorum yapabilmek için giriş yapmalısınız. Giriş yapmak için tıklayınız.

Diğer Yazılar

RedisConnectionException Hatası ve Çözümü: AbortOnConnectFail=false

31.07.2023 yasinsunmaz 782 0

Redis, popüler bir açık kaynaklı veri yapısı sunucusudur ve günümüzde birçok uygulama tarafından kullanılmaktadır. Ancak, bu tür veri tabanla...

ASP.NET Core Web API'de Parametre Bağlama Yöntemleri: FromQuery, FromBody ve FromRoute

12.07.2023 yasinsunmaz 1264 0

ASP.NET Core web API projeleri, istemcilerden gelen verileri API metotlarıyla etkileşimde bulunmak için kullanılır. Bu verileri doğru bir şekilde almak ve işlemek içi...

Deployment Stratejileri (Blue Green, Rolling Update/Rollback) Nedir?

23.06.2023 yasinsunmaz 638 0

Yazılım geliştirme sürecinde, uygulamaları güncellemek ve yeni sürümleri piyasaya sürmek önemli bir adımdır. Ancak, kullanıcıların kesintisiz hizmet a...

SonarQube Kurulumu: Adım Adım Kılavuz

18.06.2023 yasinsunmaz 1252 0

SonarQube, açık kaynaklı bir statik kod analizi platformudur ve geliştiricilere kod kalitesini, güvenliğini ve performansını iyileştirmeleri için yardımcı olur. ...

SOLID Yazılım Prensipleri

26.11.2022 yasinsunmaz 833 0

SOLID prensipleri yazılım geliştirmede başlarda anlayıp uygulaması zor olsa da buna uyarak kod geliştirmenin faydasını zamanla görebilirsiniz. Yazdığınız kodlarda sonradan yap...

Regex, Regular Expressions Genel Kullanımı

03.08.2022 yasinsunmaz 2016 0

Bir çok yazılım dilinde bazı kontroller için Regex ifadeler ihtiyaç duyabiliyoruz. Bunların en başında e-posta, telefon ve web site geliyor. Bunların doğruluğu...

Visual Studio'da Aynı Anda Birden Çok Proje Çalıştırma

21.05.2022 yasinsunmaz 3096 0

Katmanlı mimari projelerimizde ya da bir web sitenin kullanıcı arayüzü ve admin dediğimiz yönetici ekranları aynı uygulama içerisinde geliştirebiliyoruz. Admi...