HTTP Authentication Yöntemleri ve Kullanımları
HTTP Authentication (Kimlik Doğrulama) yöntemleri içerisinde en popüler olanları Basic, Digest, Bearer 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:
- Basic (RFC 7617, base64-encoded tabanlı)
- Bearer (RFC 6750, OAuth 2.0 korumalı kaynaklara erişim),
- Digest (RFC 2069, RFC 2617 ve RFC 7616),
- HOBA (RFC 7486, dijital imza tabanlı),
- Mutual (RFC 8120),
- AWS4-HMAC-SHA256 (AWS docs).
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.
- Apache sunucuda
.htaccess
ve.htpassword
ile Basic Authentication yapılandırması ile kullanmak için Tıklayınız. - 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.
- 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 2069, RFC 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ığı realm
, nonce
ve opaque
değerleri ile kullanıcı adı
ve şifre
sini 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. BuradakirequestMethod
gelen başlık içindekiGET
vePOST
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ı H1, H2 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 qop
, nc
, 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 realm
, nonce
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ığı realm
, nonce
ve opaque
, nonce
, cnonce
değerleri ile kullanıcı adı
ve şifre
sini 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ışsaMD5(requestMethod:requestURI)
formülü ile,qop
değeri “auth-int
” ayarlanmışsaMD5(requestMethod:requestURI:MD5(Body))
formülü ile H2 hash değerini oluşturur. BuradakiBody
istek içerisinde bulunan body içeriğinin tümüdür.requestMethod
gelen başlık içindekiGET
vePOST
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ışsaMD5(H1:nonce:H2)
formülü ile,qop
değişkeni “auth
” veya “auth-int
” ayarlanmışsaMD5(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ı H1, H2 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.
- Apache sunucuda
.htaccess
ve.htdigest
ile Basic Authentication yapılandırması ile kullanmak için Tıklayınız. - 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.
- 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.