IIS’te Kimlik Doğrulama: Windows Authentication ve Forms Authentication

Yıllar önce bir müşterinin IIS sunucusuna bağlandığımda, “kimlik doğrulama nasıl çalışıyor?” diye sorduğumda karşımdaki kişi “ya işte anonymous açık, bir de Windows auth var galiba” dedi. O günden bu yana bu konunun ne kadar yanlış anlaşıldığını defalarca gördüm. IIS’teki kimlik doğrulama mekanizmaları, basit bir açma/kapama işleminden çok daha derin bir konu ve yanlış yapılandırıldığında hem güvenlik açığı hem de ciddi performans sorunları doğuruyor.

IIS Kimlik Doğrulama Mimarisini Anlamak

IIS, HTTP isteği geldiğinde önce hangi kimlik doğrulama yönteminin devreye gireceğine karar verir. Bu karar, applicationHost.config ve web.config dosyalarının hiyerarşik yapısına göre şekillenir. Bir isteğin kimliği doğrulanmadan önce IIS authentication pipeline’ından geçmesi gerekir.

Temel olarak IIS’te şu kimlik doğrulama modları bulunur:

  • Anonymous Authentication: Kullanıcıdan kimlik bilgisi istenmez, IUSR hesabı kullanılır
  • Windows Authentication: NTLM veya Kerberos protokolleriyle domain/lokal hesap doğrulaması
  • Forms Authentication: ASP.NET tabanlı, cookie yönetimli kimlik doğrulama
  • Basic Authentication: Base64 kodlamalı, HTTPS olmadan kullanılmaması gereken yöntem
  • Digest Authentication: MD5 hash tabanlı, NTLM’e göre daha zayıf bir seçenek

Gerçek hayatta en çok karşılaştığım iki senaryo: iç ağ uygulamaları için Windows Authentication ve internet’e açık uygulamalar için Forms Authentication. Bu ikisini derinlemesine ele alalım.

Windows Authentication Kurulumu ve Yapılandırması

IIS Rolünü Etkinleştirme

Windows Authentication, IIS’in varsayılan kurulumunda gelmez. Önce Windows özelliği olarak yüklemeniz gerekiyor.

# PowerShell ile Windows Authentication özelliğini yükleme
Install-WindowsFeature -Name Web-Windows-Auth -IncludeManagementTools

# IIS modülünü doğrulama
Get-WindowsFeature -Name Web-Windows-Auth

Sunucu Core üzerinde çalışıyorsanız veya automation pipeline’ınızda bu adımı geçmek istiyorsanız PowerShell tercih edin. GUI üzerinden yapmak isteyenler için Server Manager üzerinden Roles and Features sihirbazında Web Server (IIS) > Security > Windows Authentication yolunu izleyin.

appcmd ile Yapılandırma

appcmd.exe hâlâ IIS yönetiminin en pratik araçlarından biri. Özellikle toplu yapılandırma ve scripting için PowerShell cmdlet’lerinden daha tutarlı davranır.

# Anonymous Authentication'ı devre dışı bırak
%windir%system32inetsrvappcmd set config "Default Web Site" ^
    -section:system.webServer/security/authentication/anonymousAuthentication ^
    /enabled:false /commit:apphost

# Windows Authentication'ı etkinleştir
%windir%system32inetsrvappcmd set config "Default Web Site" ^
    -section:system.webServer/security/authentication/windowsAuthentication ^
    /enabled:true /commit:apphost

Burada dikkat edilmesi gereken nokta /commit:apphost parametresi. Bu olmadan yapılandırma web.config dosyasına yazılır, applicationHost.config‘e değil. Bazı senaryolarda bu istenen davranış olabilir ama çoğunlukla sunucu düzeyinde kilitleme yapmanız gerektiğinde apphost kullanmalısınız.

Providers: NTLM mi, Kerberos mı?

Windows Authentication’ın hangi protokolü kullanacağı provider sırasına göre belirlenir. Bu konuda çok fazla yanlış yapılandırma görüyorum.

# Mevcut provider'ları listele
%windir%system32inetsrvappcmd list config "Default Web Site" ^
    -section:system.webServer/security/authentication/windowsAuthentication

# Kerberos'u öne al, NTLM fallback olarak kalsın
%windir%system32inetsrvappcmd set config "Default Web Site" ^
    -section:windowsAuthentication ^
    /+"providers.[value='Negotiate']" ^
    /+"providers.[value='NTLM']"

Domain ortamında Kerberos kullanmak istiyorsanız ve sunucunuz bir load balancer arkasındaysa, SPN kaydı oluşturmanız zorunludur:

# SPN kaydı oluşturma (Domain Admin yetkisi gerekli)
setspn -A HTTP/webserver.domain.local DOMAINserviceaccount
setspn -A HTTP/webserver DOMAINserviceaccount

# Mevcut SPN kayıtlarını doğrulama
setspn -L DOMAINserviceaccount

SPN olmadan Kerberos çalışmaz ve Negotiate provider NTLM’e fallback yapar. Bu da özellikle double-hop senaryolarında (IIS’ten SQL Server’a bağlanmak gibi) kimlik doğrulama hatalarına yol açar.

web.config ile Windows Authentication

ASP.NET uygulamalarında kimlik doğrulamayı hem IIS seviyesinde hem de uygulama seviyesinde yapılandırabilirsiniz:

# web.config içinde Windows Authentication örneği
# Not: Bu dosya XML formatında olsa da yapıyı göstermek için ekliyoruz
# PowerShell ile web.config'i programatik güncelleme
$webConfigPath = "C:inetpubwwwrootMyAppweb.config"
$doc = [xml](Get-Content $webConfigPath)

$authNode = $doc.SelectSingleNode("//system.web/authentication")
if ($authNode -ne $null) {
    $authNode.mode = "Windows"
}

$doc.Save($webConfigPath)
Write-Host "web.config güncellendi"

Impersonation ve UseAppPoolCredentials

Windows Authentication’da çok sık karşılaşılan bir sorun, arka taraftaki servislere (SQL, file share, vb.) erişimde kimliğin düzgün taşınmaması. useAppPoolCredentials ayarı burada kritik.

# Kernel-mode authentication için useAppPoolCredentials
%windir%system32inetsrvappcmd set config "Default Web Site" ^
    -section:windowsAuthentication ^
    /useAppPoolCredentials:true

# useKernelMode ayarı - performans için genellikle açık tutulur
%windir%system32inetsrvappcmd set config "Default Web Site" ^
    -section:windowsAuthentication ^
    /useKernelMode:true

useAppPoolCredentials:true yaparsanız, Kerberos ticket’ları Application Pool kimliği üzerinden çözümlenir. Bu özellikle Network Service veya özel bir servis hesabı kullanıyorsanız SPN yapılandırmasını basitleştirir.

Forms Authentication: Derinlemesine Bakış

Forms Authentication, ASP.NET’in yönettiği, IIS’in sadece altyapısını sağladığı bir mekanizma. Internet’e açık uygulamalar, SaaS paneller, müşteri portalları için standart yaklaşım bu.

Temel Yapılandırma Mantığı

Forms Auth’da üç temel bileşen var:

  • Login sayfası: Kullanıcının kimlik bilgilerini girdiği yer
  • Authentication ticket: Cookie içinde şifrelenmiş kimlik bilgisi
  • FormsAuthenticationModule: HTTP pipeline’ında çalışan ASP.NET modülü

IIS tarafında yapmanız gereken: Anonymous Authentication açık kalmalı (Forms Auth kullanıcıyı kendi yönlendirir), Windows Authentication kapalı olmalı.

# Forms Auth için IIS yapılandırması
# Anonymous açık, Windows kapalı
%windir%system32inetsrvappcmd set config "MyApp" ^
    -section:anonymousAuthentication /enabled:true /commit:apphost

%windir%system32inetsrvappcmd set config "MyApp" ^
    -section:windowsAuthentication /enabled:false /commit:apphost

# Doğrulama
%windir%system32inetsrvappcmd list config "MyApp" ^
    -section:system.webServer/security/authentication/anonymousAuthentication

Machine Key Yapılandırması

Forms Authentication ticket’larının güvenliği doğrudan machine key kalitesine bağlı. Web farm ortamlarında tüm sunucuların aynı machine key kullanması şart, aksi takdirde kullanıcılar load balancer’ın farklı bir sunucuya yönlendirdiğinde login sayfasına geri döner.

# PowerShell ile güçlü machine key üretme
$rng = [System.Security.Cryptography.RNGCryptoServiceProvider]::new()

$validationKeyBytes = New-Object byte[] 64
$rng.GetBytes($validationKeyBytes)
$validationKey = [System.BitConverter]::ToString($validationKeyBytes) -replace '-', ''

$decryptionKeyBytes = New-Object byte[] 32
$rng.GetBytes($decryptionKeyBytes)
$decryptionKey = [System.BitConverter]::ToString($decryptionKeyBytes) -replace '-', ''

Write-Host "validationKey: $validationKey"
Write-Host "decryptionKey: $decryptionKey"

Üretilen bu key’leri web.config dosyasının bölümüne eklemelisiniz. Web farm’da aynı key tüm node’larda kullanılmalı.

Cookie Güvenliği ve HttpOnly/Secure Bayrakları

Üretim ortamında Forms Auth cookie’lerinin mutlaka güvenli yapılandırılması gerekiyor:

# IIS URL Rewrite ile HTTP'yi HTTPS'e yönlendirme
# Bu kural web.config'e eklenir ama appcmd ile de yapılabilir
%windir%system32inetsrvappcmd set config "MyApp" ^
    -section:system.webServer/rewrite/rules ^
    /+"[name='HTTP to HTTPS',enabled='true',stopProcessing='true']"

# HTTPS zorunluluğunu SSL ayarlarıyla da yapabilirsiniz
%windir%system32inetsrvappcmd set config "MyApp" ^
    -section:system.webServer/security/access ^
    /sslFlags:Ssl

Oturum Süresi ve Sliding Expiration

Forms Auth’da timeout yönetimi sıkça sorun çıkaran bir alan. slidingExpiration aktifken her istekte cookie yenilenir, bu da her page refresh’te cookie ömrünün uzamasına neden olur.

# PowerShell ile FormsAuthentication ayarlarını kontrol etme
$webConfig = [xml](Get-Content "C:inetpubwwwrootMyAppweb.config")
$formsNode = $webConfig.SelectSingleNode("//system.web/authentication/forms")

Write-Host "Timeout: $($formsNode.timeout) dakika"
Write-Host "Sliding Expiration: $($formsNode.slidingExpiration)"
Write-Host "Cookie Name: $($formsNode.name)"
Write-Host "Login URL: $($formsNode.loginUrl)"

Hibrit Senaryo: Aynı Sitede İkisi Birden

Bir intranet uygulamasında domain kullanıcıları için Windows Auth, dışarıdan gelen misafir kullanıcılar için Forms Auth kullanmak isteyebilirsiniz. Bu senaryo IIS’te doğrudan desteklenmez ama URL Authorization ve alt site yapısıyla çözülebilir.

# Ana site: Forms Auth
# /internal alt yolu: Windows Auth
%windir%system32inetsrvappcmd set config "MyApp/internal" ^
    -section:anonymousAuthentication /enabled:false /commit:apphost

%windir%system32inetsrvappcmd set config "MyApp/internal" ^
    -section:windowsAuthentication /enabled:true /commit:apphost

# Ana site hâlâ Anonymous + Forms Auth kullanıyor
%windir%system32inetsrvappcmd set config "MyApp" ^
    -section:anonymousAuthentication /enabled:true /commit:apphost

%windir%system32inetsrvappcmd set config "MyApp" ^
    -section:windowsAuthentication /enabled:false /commit:apphost

Bu yapıda /internal altına giden istekler Windows Auth ile doğrulanırken, ana uygulamaya gidenler Forms Auth akışından geçer.

URL Authorization ile Erişim Kontrolü

Kimlik doğrulama, kimin olduğunu belirler; yetkilendirme ise ne yapabileceğini. IIS’te URL Authorization modülü bu ikinci katmanı sağlar.

# URL Authorization kuralı ekleme - sadece Admins grubuna izin ver
%windir%system32inetsrvappcmd set config "MyApp/admin" ^
    -section:system.webServer/security/authorization ^
    /+"[accessType='Allow',roles='DOMAINWebAdmins']"

%windir%system32inetsrvappcmd set config "MyApp/admin" ^
    -section:system.webServer/security/authorization ^
    /+"[accessType='Deny',users='?']"

# Kuralları listele
%windir%system32inetsrvappcmd list config "MyApp/admin" ^
    -section:system.webServer/security/authorization

users='?' anonymous kullanıcıları, users='*' tüm kullanıcıları temsil eder. Deny kurallarını Allow kurallarından önce değerlendirdiğinizde yanlışlıkla geniş erişim açma riskini azaltırsınız.

Sorun Giderme: Gerçek Hayattan Durumlar

401.1 ve 401.2 Hataları

Windows Auth’da en sık karşılaşılan hatalar. 401.1 yetkisiz erişim, 401.2 ise yapılandırma sorununu işaret eder.

# IIS loglarını analiz etme
# C:inetpublogsLogFilesW3SVC1 altında
# sc-status ve sc-substatus sütunlarına bakın

# Failed Request Tracing etkinleştirme
%windir%system32inetsrvappcmd set site "Default Web Site" ^
    -traceFailedRequestsLogging.enabled:true ^
    -traceFailedRequestsLogging.directory:"C:inetpublogsFailedReqLogFiles"

# 401 hatalarını izlemek için trace kuralı
%windir%system32inetsrvappcmd set config "Default Web Site" ^
    -section:system.webServer/tracing/traceFailedRequests ^
    /+"[path='*']" ^
    /+"[path='*'].traceAreas.[provider='WWW Server',areas='Authentication,Security',verbosity='Verbose']" ^
    /+"[path='*'].failureDefinitions.[statusCodes='401']"

Loopback Authentication Sorunu

Aynı sunucu üzerinde başka bir sitenin IIS üzerinden Windows Auth ile çağrılması çalışmaz, bu Windows’un loopback protection mekanizması yüzünden. Registry’den çözülür:

# Loopback protection'ı devre dışı bırakma (dikkatli kullanın)
# Güvenlik riski yaratır, sadece test/dev ortamında önerilir
reg add HKLMSYSTEMCurrentControlSetControlLsa ^
    /v DisableLoopbackCheck /t REG_DWORD /d 1 /f

# Daha güvenli alternatif: BackConnectionHostNames
reg add HKLMSYSTEMCurrentControlSetControlLsaMSV1_0 ^
    /v BackConnectionHostNames /t REG_MULTI_SZ /d "webserver.domain.local" /f

BackConnectionHostNames yöntemi daha güvenli çünkü sadece belirttiğiniz hostname’ler için loopback’e izin verir, tümünü devre dışı bırakmaz.

Forms Auth Cookie Sorunları

Kullanıcılar sürekli login sayfasına dönüyorsa ve web farm kullanıyorsanız:

# Tüm web sunucularının machine key'ini karşılaştırma
# Her sunucuda çalıştırın, çıktılar aynı olmalı
$webConfig = [xml](Get-Content "C:inetpubwwwrootMyAppweb.config")
$machineKey = $webConfig.SelectSingleNode("//system.web/machineKey")
Write-Host "Server: $env:COMPUTERNAME"
Write-Host "ValidationKey: $($machineKey.validationKey)"
Write-Host "DecryptionKey: $($machineKey.decryptionKey)"

Eğer key’ler farklıysa, AutoGenerate kullanılıyor demektir ve her sunucu kendi key’ini oluşturmuştur. Yukarıda gösterdiğim yöntemle sabit key üretip tüm sunuculara dağıtın.

Güvenlik Sertleştirme Notları

Kimlik doğrulama yapılandırmasının yanında birkaç temel sertleştirme adımı mutlaka uygulanmalı:

  • NTLM’i mümkünse devre dışı bırakın: Kerberos daha güvenli, NTLM pass-the-hash saldırılarına açık
  • Extended Protection for Authentication (EPA) aktif edin: Man-in-the-middle saldırılarına karşı
  • Forms Auth timeout’unu iş ihtiyacına göre ayarlayın: 20-30 dakika genellikle dengeli bir değer
  • Cookie prefix kullanın: __Secure- veya __Host- prefix’leri modern tarayıcılarda ek güvenlik sağlar
  • requireSSL Forms Auth için zorunlu yapın: HTTP üzerinden Forms Auth ticket’ı iletmek ciddi risk
# Extended Protection etkinleştirme
%windir%system32inetsrvappcmd set config "Default Web Site" ^
    -section:windowsAuthentication ^
    /extendedProtection.tokenChecking:Require ^
    /extendedProtection.flags:None

EPA’yı Require olarak ayarlamak bazı eski istemcileri kırabilir. Allow ile başlayıp ortamınızı test edin, sorun yoksa Require‘a geçin.

Sonuç

IIS kimlik doğrulama konusu, “bir ayar aç, tamam” diye geçiştirilebilecek bir şey değil. Windows Authentication’da SPN yapılandırması, Kerberos/NTLM provider sırası, kernel-mode authentication ve double-hop senaryoları her biri kendi başına bir problem kaynağı. Forms Authentication’da ise machine key yönetimi, cookie güvenliği ve web farm uyumluluğu dikkat gerektiriyor.

En sık gördüğüm hata: Windows Auth açılmış ama Anonymous da açık kalmış, sonra uygulama bazen anonim bazen kimlikli çalışıyor ve neden olduğu anlaşılamıyor. İkincisi: Forms Auth kurulmuş ama machine key AutoGenerate olarak bırakılmış, load balancer eklenince kullanıcılar çıldırıyor.

Bu yazıda ele aldığım appcmd komutları ve PowerShell scriptleri, günlük operasyonlarda doğrudan kullanılabilecek şekilde hazırlandı. Automation’a önem veriyorsanız bu komutları Ansible, DSC veya basit batch scriptlerine entegre ederek yapılandırma kaymasını önleyebilirsiniz. Kimlik doğrulama yapılandırması, bir kez yapılıp unutulan değil, periyodik olarak gözden geçirilmesi gereken bir alan.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir