Daha önce iki yazımda, HTTP protokolünde kimlik doğrulama işleminin nasıl yapıldığından kısaca bahsetmiştim. Ancak gelen yoğun ilgiye istinaden bunun detaylarından bahsetme gereği duydum.
Tarayıcıdan ve karşıdaki web sunucusundan bağımsız olarak, normal koşullarda, sunucuya gönderilen ilk istek, hiçbir kimlik bilgisi içermez. Bunun da aslında çok basit ve mantıklı bir nedeni vardır: İstekte bulunduğumuz web sunucusunun, istekte bulunduğumuz kaynak için kimlik doğrulama isteyip istemeyeceğini nereden bilebiliriz? Cevap kolay, bilemeyiz. Bu nedenle tüm tarayıcılar, önce anonim olarak bir istekte bulunur. Aşağıda örnek bir isteğin başlık (header) bilgileri bulunuyor:
GET /default.aspx HTTP/1.1Accept-Language: en-usUA-CPU: x86Accept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; .NET CLR 2.0.50727; .NET CLR 1.1.4322; NET CLR 3.0.04506; .NET CLR 3.5.21022;)Connection: Keep-AliveHost: www.contoso.com
Yukarıdaki satırlardan sadece ilk ve son satırlar zorunludur. Bu nedenle şu aşamada diğer satırların ne anlama geldiği üzerinde durmayacağım. İlk satırda, hangi "verb" ile istekte bulunduğumuz (ki burada GET kullanmışız; veri gönderiyor olsaydık POST olacaktı), görüntülemek istediğimiz sayfanın adını ve son olarak da kullanmak istediğimiz HTTP versiyonunu belirtiyoruz. Son satırda da, istekte bulunduğumuz sayfanın bulunduğu web sitesinin adını veriyoruz.
Yukarıdaki satırların hiçbiri, kimlik bilgisi içermez. Zaten başta da belirttiğim gibi, ilk istekler neredeyse hiçbir zaman kimlik bilgisi içermez.
Eğer istediğimiz sayfaya "anonim" olarak erişilebiliyorsa, sunucu bize içeriği gönderecektir. Ancak eğer sadece belirli kişiler görüntüleyebiliyorsa o sayfayı, sunucu bize aşağıdaki gibi bir yanıt döner:
HTTP/1.1 401 UnauthorizedContent-Length: 1656Content-Type: text/htmlServer: Microsoft-IIS/6.0WWW-Authenticate: NegotiateWWW-Authenticate: NTLMX-Powered-By: ASP.NETDate: Fri, 2 Jan 2009 06:38:47 GMT
Yukarıda görüldüğü gibi, bir "401 Unauthorized" hatası aldık. Gelen yanıtın içeriğinde bu hatanın tam olarak "HTTP Error 401.2 - Unauthorized: Access is denied due to server configuration." olduğunu görecektik. Burada önemli olan "WWW-Authenticate" başlıklarıdır. Bu başlıklarla sunucu bize hangi tür kimlik doğrulama yöntemlerini desteklediğini söyler. Burada "Negotiate" ve "NTLM" desteklediğini görüyoruz. Bunların dışında "Basic" ve "Digest" gibi türler de olabilirdi.
Bazen, yukarıda olduğu gibi, bir web sunucusu birden fazla tür kimlik denetimi destekleyebilir. Tarayıcı, duruma göre "kullanabileceği" en "güvenli" yöntemi tercih eder. Bu, eğer mümkünse "Negotiate", yani "Kerberos" veya "NTLM"dir.
Tarayıcımız yukarıdaki durum için "Negotiate" kullanmaya karar vermiş olsun. Şimdi bizim adımıza ikinci bir karar vermesi gerekmektedir: Bize kullanıcı adı ve şifre mi soracaktır, yoksa kendisi mi bu işi halledecektir? Buna karar verirken bakacağı yer (bu, Internet Explorer'da değiştirilebilen bir ayardır) istekte bulunulan sitenin "yerel intranet" sitesi olup olmadığıdır. Buna karar verirken de, önce o sitesnin kendisindeki "yerel intranet" siteleri listesinde olup olmadığına bakar. Burada yoksa adreste nokta (.) karakteri geçip geçmediğine bakar. Eğer geçmiyorsa yine "yerel intranet" sitesi olduğunu varsayar.
Eğer sonuç olarak "yerel intranet" sitesi olduğuna karar verirse, bize şifre sormaz ve geri kalan adımları kendisi halleder. Aksi takdirde bize bu aşamada kullanıcı adımızı ve şifremizi sorar ve biz giriş yaptıktan sonra aşağıdaki adımlara devam eder.
Devam etmeden önce, eğer "Basic" kullanacak olsaydık ne olurdu, bundan bahsedelim: "Basic" kimlik doğrulama metodunda, kullanıcı adı ve şifre direkt olarak sunucuya gönderilir. Tarayıcımız bunu bilemeyeceğinden bize mutlaka sorar. Sonra açık olarak (şifrelemeden) sunucuya gönderir (bu nedenle SSL'siz kullanımı önerilmez). Eğer ilgili kaynağa erişim hakkımız varsa, direkt olarak bu ikinci adımda sayfa içeriğini alırız. Yani işlem burada biter.
"NTLM" ve "Negotiate" yöntemlerinde (yani "integrated windows authentication" seçili olan durumda) şifrenin kendisi değil, bir "jeton" (token) gönderilir. Bu da iki aşamada gerçekleşir. İlk aşamada, yani bu adımda, tarayıcı, aşağıdakine benzer bir istekte bulunur:
GET /default.aspx HTTP/1.1Accept-Language: en-usUA-CPU: x86Accept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.0.04506; .NET CLR 3.5.21022;)Authorization: Negotiate TlRMTVNTUAABAAAAAAAA4gAAAAAAAAAAAAAAAAAAAAAGAAXEAAAADw==Connection: Keep-AliveHost: www.contoso.com
Yukarıda da görüldüğü üzere, önceki isteğin aynısı yeniden gönderiliyor. Tek fark, daha öncekinde olmayan "Authorization" başlığının da bulunmasıdır. Burada, tarayıcımızın "Negotiate" kullanmaya karar verdiğini görüyoruz. Sonrasında gördüğümüz karakter dizisi ise bizim kullanıcı adımız, makine adımız ve bağlı olduğumuz alan adımızı içeriyor olacaktır. Buna yanıt olarak da web sunucusu aşağıdaki gibi bir tane daha 401 hatası dönecektir:
HTTP/1.1 401 UnauthorizedContent-Length: 1539Content-Type: text/htmlServer: Microsoft-IIS/6.0WWW-Authenticate: Negotiate TlRMTVNTUAAAAAAAAAAAAAAAAAAVgOONPEAQ+EUPDsYAAAAAAAAAAAIBAgFIAAAAaaaaaaaaAAAAAAAAAAAAAE4ARQBSAFMAAgAQAFAAQQBSAF...HQAqwerewqwerewqwerewqwAGMAcgBvAHMAbwAAAAAAAAAAAAAAbQAFACwAZQB4AHQAcgBhAG4AZQB0ACQQQQQQQQQQQQQvAHMAbwBmAHQALgBjAG8AbQAAAAAAX-Powered-By: ASP.NETDate: Fri, 02 Jan 2009 07:48:51 GMT
Bu seferki 401 hatasının tam açıklaması ise şöyledir: "HTTP Error 401.1 - Unauthorized: Access is denied due to invalid credentials." Aslında bu da çok mantıklı, çünkü biz henüz şifre veya jeton (token) göndermedik. Web sunucunun bize gönderdiği "WWW-Authentıcate" başlığındaki değer de duruma göre ya "ticket granting ticket"tır, ya da "challenge"dır (NTLM mi, Kerberos mu kullanıldığına göre değişir). Bunların ne olduğunun detayları HTTP protokolü açısından bakıldığında bizi ilgilendirmediğinden burada bahsetmeyeceğim. İlgilenenler yazımın sonundaki makalelerde bu detayları bulabilirler.
İkinci defa 401 hatası aldıktan sonra tarayıcımız bir istek daha gönderir:
GET / HTTP/1.1Accept-Language: en-usUA-CPU: x86Accept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.0.04506; .NET CLR 3.5.21022;)Host: www.contoso.comConnection: Keep-AliveAuthorization: Negotiate TlRMTVNTUAADAAAAGAAYAIIAAABmAWYBmgAAABQAFABYAAAACgAKAGwAAAAMABABABABABABABAAAAAAAAAAAAAAAABBBBAAAAAABBBKztSI/+IDomk69k0ASQBEAEQATABFAEUAQWBYSAAEEVJHKDRSSAWEAGMARQBOAEsAMAA4ADHlK0Du5P...ALgBjAG8AbQAWEBXasdaweGHJSSDSDFhdgjd0AC4AbQAACCCCAAGSAFMAbwBmAHQALgBjAG8AbQAIADAAMAAAAAAAAAAAAAAAADAAAIpoewZRe+AAAAAAAAAAAAAAAAAAAAAAAAAAAusZrrr1AAAAAAAAAAD7FFSas/AASDDcfasshcp
Bu defa tarayıcımızın gonderdiği "Authorization" başlığı, Kerberos kullanılıyorsa bizim "ticket"ımız, NTLM kullanılıyorsa şifremiz ve sunucudan alınan "challenge"ın matematiksel bir karşımıdır. Sunucu bunu aldıktan sonra kontrol ettirir (kullanıcı yerel bir kullanıcı ise Windows'a değilse "Domain Controller"a sorar). Eğer kullanıcının bilgileri doğruysa, ve ilgili kaynağa erişim hakkı varsa istenilen içerik kullanıcıya gönderilir. Aksi takdirde, yine duruma göre bir tane daha 40 hatası gönderilir. Bu durumda, tarayıcımız bize yeniden kullanıcı adı ve şifre sorabilir veya 401 hatasını direkt olarak bize gösterebilir.
SONUÇ
Tüm bunları toparlayacak olursak, IIS loglarında göreceğimiz her 401 hatası, sorun olduğu anlamına gelmez. Sonraki iki isteğin yanıtını da kontrol etmemiz gerekir.
Bu arada bir dipnot: Aynı kimlik doğrulama mekanizması "proxy"ler için de geçerlidir, çünkü onlar da HTTP protoklünü kullanırlar. Yani, örneğin ISA Server loglarında göreceğimiz "407 - Proxy authentication required." hataları için de yukarıdakiler geçerlidir.
REFERANSLAR
401.1 and 401.2-Authentication Problems (IIS 6.0)http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/8feeaa51-c634-4de3-bfdc-e922d195a45e.mspx?mfr=true
How IIS authenticates browser clientshttp://support.microsoft.com/?id=264921
Kerberos authentication and troubleshooting delegation issueshttp://support.microsoft.com/?id=907272
How to troubleshoot Kerberos-related issues in IIShttp://support.microsoft.com/?id=326985
CENK ISCAN