HTTP Authentication Yöntemleri ve Kullanımları

HTTP Authentication (Kimlik Doğrulama) yöntemleri içerisinde en popüler olanları BasicDigestBearer ve NTLM doğrulama mekanizmalarıdır. Bu yazımızda Basic ve Digest yöntemlerinin özelliklerini, kullanım şekillerini ve örnek yapılandırmasını detaylıca inceleyeceğiz.

HTTP, uygulama katmanında çalışan ve internetin temelini oluşturan bir protokoldür. Bu protokol ile gezindiğimiz internet sayfaları ve uygulamalar kendilerini korumak için kimlik doğrulama yöntemlerine başvurabilirler. Hatta siz bile sayfalarınızı korumak amacıyla bu yöntemlerden birini seçebilirsiniz. Böylece korunan sayfalara erişebilmek için kullanıcıların yetkilendirilmiş bir ziyaretçi olması gerekecektir. Öyleyse ilk olarak bir anlam karmaşasına mahal veren Authentication ve Authorization arasındaki farkı anlamakla başlayalım.

1. Authentication ve Authorization Arasındaki Fark

Kriptoloji yazıları hazırlarken birçok kişinin Encryption ve Hash kavramlarını birbirleriyle karıştırdığını farketmiştim. Yine buna benzer bir karmaşa durumu HTTP Authentication ve Authorization arasında da var maalesef. Bu nedenle ilk olarak bu iki kavramın farkını anlayarak başlayalım ve ileride client ile server tarafındaki hazırlıkları yaparken kimin neyi yaptığını karıştırmayalım.

Authentication, bir varlığın kendi kimliğini kanıtlamasıdır. Başka bir deyişle, Kimlik Doğrulama sizin söylediğiniz kişi olduğunuzu kanıtlar. Bunu güvenilir bir makam tarafından talepte bulunan kişiye, bir polis memuru gibi, gerçekte kim olduğunuzu söyleyen ve kanıt olarak kullanabileceğiniz bir kimlik kartına benzetebiliriz.

Authorization, bir varlığın erişim hakkını, kimliğini kanıtladığı zamandır. Başka bir deyişle, Yetkilendirme, istekte bulunma hakkınızın olduğunu kanıtlar. Örneğin çalıştığınız işyerinde sadece personellerin girebileceği alanlarda bulunabilirsiniz ve zaten bir çalışan olduğunuz için sizi kimse sorgulamaz. Fakat bir müşteri bu alanlara yetkisi olmadığı için giremeyecektir.

2. HTTP Authentication Yöntemleri

Authentication ve Authorization arasındaki farkı anladığımıza göre Authentication yani Kimlik Doğrulama kavramında artık HTTP ile gelen ziyaretçilerin kendilerini ispatlamasını isteyeceğimizi farketmişsinizdir. Tabi birçok kimlik doğrulama yöntemi olmasına rağmen bu yazımızda en çok kullanılan Basic ve Digest doğrulama yöntemlerini inceleyeceğiz. Tabi yeri gelmişken tüm yöntemlerin standart numarasını da verelim:

2.1 Basic Authentication

HTTP Basic Authentication (Temel kimlik doğrulaması), istemcinin istekte bulunurken kullanıcı adı ve parola sağlaması için kullanılan bir yöntemdir. Sunucu tarafında belirli bir dosya veya tüm çalışma alanı için kurulabilen bu doğrulama yönteminde istemcinin doğru giriş bilgilerini girmesi gerekmektedir.

Peki bu doğrulama yönteminin aşamaları nedir? Tam olarak nasıl çalışır?

Doğrulama Aşamaları

Basic Authentication ile kullanacağımız bir sayfada gerçekleşen HTTP el sıkışma aşamaları aşağıda gösterildiği gibidir.

1. Tarayıcı (İstemci), Basic Authentication kullanan sayfaya istek atar.

2. Sunucu, HTTP durum kodunu (401) ve istemcinin Basic Authentication başlatması gerektiğini belirten Basic değerli WWW-Authenticate değişkenini http başlığıyla gönderir.

WWW-Authenticate : Basic

3. İstemci tarayıcısı bu başlıkla karşılaştığında aşağıdaki gibi kullanıcı adı ve şifre için bir giriş alanına sahip pencereyi oluşturur.

4. İstemci, açılır pencerede kullanıcı adı ve şifre bilgilerini girer ve gönderir. Burada tarayıcı, base64 kodlamasını kullanarak girilen kullanıcı adını ve şifreyi iki nokta üst üste işaretiyle kodlar. Örneğin, kullanıcı adını admin ve şifreyi 12345 olarak girdiğinizi varsayalım. Tarayıcı bunu aşağıdaki gibi kodlayacaktır.

Kodlama : Base64Encode('admin:12345')
Çıktı   : YWRtaW46MTIzNDU=

5. İstemci tarayıcısı daha sonra Authorization başlığının içine bu Base64 değerini ekleyerek gönderir. Aşağıdaki gibi kodlanmış değerden önce Basic dizesini başına da ekleneceğini unutmayın.

Authorization : Basic YWRtaW46MTIzNDU=

6. Sunucu, Authorization başlığında istemci tarafından gönderilen encode değerini sunucuda kayıtlı olan kullanı adı ve şifrenin aynı şekilde alınmış base64 encode değeri ile karşılaştırır. Her iki değer de eşleşirse, istenen verilerle birlikte HTTP durum kodu 200‘ü gönderir. Ancak encode değerleri eşleşmezse, sunucu WWW-Authenticate ile birlikte belirtildiği gibi 401 gönderir ve 2. adıma döner.

Basic Auth. ile hazırladığım örnek bir sayfada doğrulama sonrası yetki almış bir şekilde gezindiğim sayfanın HTTP başlığında aşağıdaki resimde olduğu gibi Authorization etiketini görürüz.

NOT: Basic Authentication ile yapılan kimlik doğrulaması işlemlerinde encryption veya hash alma işlemleri kullanılmaz ve Base64 encode değeri clear-text olarak gönderilir. Bu nedenle HTTPS olmayan sayfalarınızda güvenlik açısından Basic Auth. kullanmamalısınız. Aksi takdirde ağı dinleyen bir kişi base64 ile encode ettiğiniz kullanıcıadı:şifre kombinasyonunuzu rahatlıkla görüntüleyebilir ve yetkisiz girişler meydana gelebilir.

Tam olarak bundan bahsediyordum 🙂

Kullanma Şekilleri

Basic Authentication, HTTP protokolü ile kullanılabilen bir doğrulama yöntemi olduğu için tüm programlama dillerinde ve sistemlerde rahatlıkla uygulayabilirsiniz. Kullanımına dair birkaç örneği ise hemen verelim.

  1. Apache sunucuda .htaccess ve .htpassword ile Basic Authentication yapılandırması ile kullanmak için Tıklayınız.
  2. Python programlama dilinde ise Flask ile hazırladığımız sitelerde yine Basic Authentication yapılandırmasını kolaylıkla yapabiliriz. Flask örneğini incelemek için Tıklayınız.
  3. PHP ile Basic Authentication yapabilmek için aşağıdaki gibi basit bir kod kullanabilirsiniz.
<?php
    if (!isset($_SERVER['PHP_AUTH_USER'])) {
            header('WWW-Authenticate: Basic realm="TestBolgesi"');
            header('HTTP/1.0 401 Unauthorized');
            echo '401: Yetkisiz giriş, önce kimliğinizi doğrulayın.';
            exit;
    } else {
            echo "<p>Merhaba {$_SERVER['PHP_AUTH_USER']}.</p>";
            echo "<p>Parola olarak {$_SERVER['PHP_AUTH_PW']} verdiniz.</p>";
    }
?>

Burada Authorization parametresi olmadan ilk istek geldiğinde bir kullanıcı adı girilmemişse hata mesajını veriyor ve WWW-Authenticate parametresi ile kullanıcı adı ve şifre penceresini açıyoruz. Ardından girilen bilgileri bu örnekte sadece ekrana basıyoruz. Siz kodu daha da geliştirerek gelen kullanıcı adı $_SERVER['PHP_AUTH_USER'] ve şifreyi $_SERVER['PHP_AUTH_PW'] kontrol edip doğru olmaması halinde tekrar WWW-Authenticate isteği atabilir, doğruysa 200 kodu döndürebiliriz.

2.2 Digest Authentication

HTTP Digest Authentication (Özet kimlik doğrulaması), yine aynı şekilde kullanıcıdan bir kullanıcı adı ve parola ile kendini kanıtlamasını ister. Fakat bunu yaparken Basic Authentication yönteminde olduğu gibi sadece base64 ile encode edip clear-text göndermek yerine belirli kombinasyonları rastgele bir nonce değeri ile MD5 hashini alarak verinin gizliliğini sağlar.

Şimdi de Digest Authentication yönteminin aşamalarını sırasıyla inceleyelim:

Doğrulama Aşamaları

Digest Authentication RFC 2069RFC 2617 ve RFC 7616 olmak üzere üç standarta sahiptir. En son çıkan RFC 7616, RFC 2617 de kullanılan MD5 hash algoritmasına ek olarak SHA-256 ve SHA-512/256 algoritmalarını da destekler. Fakat bazı tarayıcılar ile halen uyumlu değildir. Bu sebeple aşağıda RFC 2069 ve RFC 2617 standartları ile kullanacağımız bir sayfada gerçekleşen HTTP el sıkışma aşamalarını göstereceğiz. İlk olarak RFC 2069 ile başlayalım.

1. Tarayıcı (İstemci), Digest Authentication kullanan sayfaya istek atar.

2. Sunucu, HTTP durum kodunu (401) ve istemcinin Digest Authentication başlatması gerektiğini belirten Digest değerli WWW-Authenticate değişkenini HTTP başlığıyla gönderir. Tabi Digest‘in yanında birden fazla değişkende başlıkta bulunur. Bunların neler olduğunu inceleyelim.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest realm="Test Alanı",
  nonce = "NjM0NjkxNDY3NDU3N",
    opaque = "654632146465"

Burada realm rastgele bir çalışma alanı isimdir. Bu çalışma alanına dahil ettiğiniz tüm sayfalarda aynı kullanıcı adı ve şifre geçerli olacağı anlaşılır. Özetle rastgele bir isim, sayı vs seçebilirsiniz. nonce ise eşsiz ve rastgele bir değerdir. İster sayılardan oluşan ister karakterlerden oluşan rastgele bir karakter dizisi oluşturabilirsiniz. opaque da nonce ile aynı şekilde eşsiz ve rastgele bir değerdir. Bu iki değişken her istekte değişmelidir ve farklı olmalıdır.

3. İstemci tarayıcısı bu başlıkla karşılaştığında aldığı realmnonce ve opaque değerleri ile kullanıcı adı ve şifresini kullanarak 3 farklı MD5 ile hash değeri oluşturur.

  • İlk olarak MD5(username:realm:password) formülü ile H1 hash değerini oluşturur.
  • İkinci olarak MD5(requestMethod:requestURI) formülü ile H2 hash değerini oluşturur. Buradaki requestMethod gelen başlık içindeki GET ve POST değerlerinden hangisi kullanılmışsa odur. requestURI de istekte bulunduğumuz sayfanın adresidir. Örneğin “/dir/index.html”
  • Son olarak ise MD5(H1:nonce:H2) formülü ile RESPONSE hash değeri oluşturulur.

Ardından istemci tarayıcısı sunucuya aşağıdaki isteği gönderir.

Authorization: Digest username="%1", realm="%2", nonce="%3", opaque="%4", uri="%5", response="%6"'
  • %1 = kullanıcı adı
  • %2 = sunucudan gelen realm değeri
  • %3 = sunucudan gelen nonce değeri
  • %4 = sunucudan gelen opaque değeri
  • %5 = istekte bulunduğumuz sayfa uri değeri
  • %6 = yukarıda oluşturduğumuz RESPONSE değeri

4. Sunucu bu başlığı aldığında gelen kullanıcı isminin şifre karşılığını veritabanı veya kullandığı depolama sisteminde çekerek aynı H1H2 ve RESPONSE MD5 hash değerlerini oluşturur. Ardından gelen RESPONSE ve kendi oluşturduğu RESPONSE değerini karşılaştırarak eşitse yetki verme işlemini yapar ve sayfayı sunar.

NOT: Buraya kadar anlatılan 4 aşama RFC 2069 standartında ki basit kullanımdır ve şifrenin güvenliğini başarılı bir şekilde sağlar. Şimdi ise Body içindeki verinin de bütünlüğünü sağlamak için RFC 2617 standartı ile gelen qopnc, and cnonce değerlerini kullanıp aynı aşamaları tekrarlayalım.

1. Tarayıcı (İstemci), Digest Authentication kullanan sayfaya istek atar.

2. Sunucu, HTTP durum kodunu (401) ve istemcinin Digest Authentication başlatması gerektiğini belirten Digest değerli WWW-Authenticate değişkenini HTTP başlığıyla gönderir. Digest‘in yanında önceki örnekte gelen realmnonce ve opaque değişkenleri yine gelmiş olur. Bunlara ek olarak qop değeri desunucu tarafından gönderilebilir.

qop değeri ayarlar “auth” veya “auth-int” değerlerinden birisi veya her ikisi olabilir. Eğer qop gelen istekte yoksa öntanımlı olarak “auth” kabul edilir.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest realm="Test Alanı",
  nonce = "NjM0NjkxNDY3NDU3N",
    opaque = "654632146465",
    qop = "auth"

3. İstemci tarayıcısı bu başlıkla karşılaştığında aldığı realmnonce ve opaquenoncecnonce değerleri ile kullanıcı adı ve şifresini kullanarak response isimli hash değerini oluşturur.

  • İlk olarak MD5(username:realm:password) formülü ile H1 hash değerini oluşturur.
  • İkinci olarak eğer qop değişkeni ayarlanmamışsa veya “auth” olarak ayarlanmışsa MD5(requestMethod:requestURI) formülü ile, qop değeri “auth-int” ayarlanmışsa MD5(requestMethod:requestURI:MD5(Body)) formülü ile H2 hash değerini oluşturur. Buradaki Body istek içerisinde bulunan body içeriğinin tümüdür. requestMethod gelen başlık içindeki GET ve POST değerlerinden hangisi kullanılmışsa odur. requestURI de istekte bulunduğumuz sayfanın adresidir. Örneğin “/dir/index.html”.
  • Son olarak ise yine eğer qop değişkeni ayarlanmamışsa MD5(H1:nonce:H2) formülü ile, qop değişkeni “auth” veya “auth-int” ayarlanmışsa MD5(H1:nonce:nonceCount:cnonce:qop:H2) formülü ile RESPONSE hash değeri oluşturulur.

Yukarıda ki üçüncü adımda yer alan nonceCount (nc),istemcinin belirli bir nonce değeri ile gönderdiği istek sayısının onaltılık sayısıdır. Bu şekilde sunucu replay saldırılarına karşı koruma sağlayabilir. cnonce ise sunucunun oluşturduğu eşsiz nonce değeri gibi istemcinin oluşturduğu eşsiz ve rastgele bir değerdir.

Ardından istemci tarayıcısı sunucuya aşağıdaki gibi bir istek gönderir.

GET /dir/index.html HTTP/1.0
Host: localhost
Authorization: Digest username="kerteriz",
                     realm="Test Alanı",
                     nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
                     uri="/dir/index.html",
                     qop=auth,
                     nc=00000001,
                     cnonce="0a4f113b",
                     response="6629fae49393a05397450978507c4ef1",
                     opaque="5ccc069c403ebaf9f0171e9517f40e41"

4. Sunucu bu başlığı aldığında gelen kullanıcı isminin şifre karşılığını veritabanı veya kullandığı depolama sisteminde çekerek aynı H1H2 ve RESPONSE MD5 hash değerlerini oluşturur aynı istemcide olduğu gibi oluşturur. Ardından gelen RESPONSE ve kendi oluşturduğu RESPONSE değerini karşılaştırarak eşitse yetki verme işlemini yapar ve sayfayı sunar.

Örnek bir ağ paketi şu şekildedir:

Kullanma Şekilleri

Digest Authentication, HTTP protokolü ile kullanılabilen bir doğrulama yöntemi olduğu için tüm programlama dillerinde ve sistemlerde rahatlıkla uygulayabilirsiniz. Kullanımına dair birkaç örneği ise hemen verelim.

  1. Apache sunucuda .htaccess ve .htdigest ile Basic Authentication yapılandırması ile kullanmak için Tıklayınız.
  2. PHP ile Basic Authentication yapabilmek için aşağıdaki gibi basit bir kod kullanabilirsiniz. Örnek kodu görmek için Tıklayınız.
  3. Python programlama dilinde ise Flask ile hazırladığımız sitelerde yine Digest Authentication yapılandırmasını kolaylıkla yapabiliriz. Flask örneğini incelemek için Tıklayınız.

3. SONUÇ

Şimdiye kadar mevcut HTTP kimlik doğrulama yöntemlerinizin ne olduğu ve nasıl kullanıldığı hakkında özet bir makale sunduk. Temel Kimlik Doğrulaması, uygulanması en kolay ve en az güvenli olanıdır. Kullanıcı adları ve parolalar Base64‘te kodlanır, ancak sunucuya düz metin olarak gönderilir. Özet Kimlik Doğrulama, MD5 üzerinden kimlik doğrulama verileri göndererek Temel yöntemin iyileştirilmiş halidir. MD5 hala güçlü bir hash algoritması olmasa da, kod çözülmesi, Temel Kimlik Doğrulamanın düz metin / Base64 yönteminden çok daha zordur. Tabi her biri bu halleriyle bile açıklara sahip ama yeni gelecek RFC versiyonlarıyla giderek güçleneceklerdir.

Son olarak bu kimlik doğrulama yöntemlerine ek olarak mutlaka SSL kullanmalısınız. Çünkü SSL genel internet üzerinden kullanıcı kimlik doğrulama verilerini göndermenin en modern ve güvenli yöntemidir. Ancak SSL kullanılamıyorsa, lütfen Basic Auth. yerine Digest Auth. kullanınız.