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.
