JWT içindeki alanları okumak kolaydır; o alanların güvenilir olduğunu ve istenen işlem için yeterli olduğunu göstermek ayrı iştir. Kimlik doğrulama “çağıran kim?”, yetkilendirme “bu işlemi yapabilir mi?” sorusuna cevap verir. API arşivimdeki claim tabanlı yaklaşımı anlatırken bu iki sınırı özellikle ayrı tutuyorum.
Bu örnek JWT doğrulamıyor
Aşağıdaki .NET 10 konsol kodu bellekte ClaimsIdentity oluşturur. “demo” authentication type değeri verildiği için IsAuthenticated true olur. Burada token üretimi, imza kontrolü, issuer veya audience doğrulaması yok. Bu farkı atlamak, yerel bir nesnenin özelliğini güvenlik kanıtı sanmaya yol açabilir.
using System.Security.Claims;
var identity=new ClaimsIdentity(new[]{
new Claim(ClaimTypes.NameIdentifier,"7"),
new Claim("permission","article:edit")
},"demo");
var user=new ClaimsPrincipal(identity);
Console.WriteLine(user.Identity?.IsAuthenticated==true);
Console.WriteLine(user.HasClaim("permission","article:edit"));
Console.WriteLine(user.HasClaim("permission","user:delete"));
Beklenen sonuçlar True, True ve False. Kullanıcıda article:edit claim'i var, user:delete yok. Bu kontrolün anlatımı, gerçek HTTP isteğinden güvenilir ClaimsPrincipal elde edildikten sonraki yetki kararına hazırlıktır. İstemciden alınan JSON ile aynı nesneyi oluşturup yetkili kullanıcı kabul etmek doğru değildir.
Token'ı decode etmek ile doğrulamak farklı adımlar
JWT payload'ı okunabilir; okunması imzasının geçerli olduğunu göstermez. Sunucu kabul etmeden önce imzayı güvenilen anahtarla, beklenen issuer ve audience değerleriyle ve zaman koşullarıyla kontrol etmelidir. Kabul edilen algoritma ve anahtar kaynağı da uygulamanın güven modeline aittir. Bu yapılandırma tarayıcıdaki rol kontrolüne bırakılamaz.
exp ve nbf gibi zaman alanları yanlış olsa da token metni teknik olarak okunabilir. Saat toleransı bilinçli seçilir. Yenileme token'ı, erişim token'ı ve sağlayıcıya ait token farklı görevler taşıyabilir; birinin doğrulanmış olması diğerini API'nin erişim token'ı yapmaz. İmza anahtarları ve bağlantı sırları kaynak koduna konmaz.
Policy kontrolünü endpoint'te görünür kılmak
Gerçek API'de article:edit izni bir policy gereksinimi olarak tanımlanabilir ve düzenleme endpoint'ine uygulanabilir. Böylece kontrol her controller içinde serbest metin karşılaştırmalarıyla çoğalmaz. Claim adı, değer eşlemesi ve rol claim'i türü kimlik sağlayıcı sözleşmesiyle tutarlı olmalı; kullanıcı adını veya görünür rol etiketini izin anahtarı gibi kullanmam.
Ancak article:edit bütün yazılara erişim demek olmayabilir. Yazının sahibi, birim veya tenant kapsamı ayrıca sorguya uygulanmalıdır. İzni olan kullanıcı farklı kişiye ait Id'yi gönderdiğinde kaydı döndürmemek ya da işlemi reddetmek gerekir. Menüde bir düğmeyi gizlemek bu veri sınırını sağlamaz.
401 ile 403'ü istemcide ayırmak
Kimlik yok veya erişim token'ı kabul edilmiyorsa 401; kimlik kabul edilip izin yetersizse 403 beklenir. 403'te aynı kullanıcıyı tekrar login'e göndermek genellikle aynı hataya geri döndürür. Oturum yenileme varsa sınırlı ve tek uçuşlu olmalı; her başarısız istek kendi sonsuz döngüsünü başlatmamalı.
Bu makale belirli bir tarayıcı token saklama çözümünü dayatmıyor. Cookie ile çalışan bir uygulamada HttpOnly ve CSRF, bearer token kullanan istemcide ise token'ın maruz kalma yüzeyi ayrı değerlendirilir. localStorage içindeki bir isAdmin veya permission değeri sunucuda yetki kanıtı sayılmaz.
Negatif testler güvenlik sözleşmesini gösterir
Geçerli token ve izinle başarıyı denedikten sonra eksik token, bozuk imza, yanlış audience, süresi geçmiş token ve eksik izin durumlarını sınarım. Kaynak kapsamı dışındaki Id de ayrı bir testtir. Hata tanısında token'ın tamamını loglamak yerine ret nedeni ve correlation ID gibi dar bilgiler yeterli olabilir. Konsol örneğinin True çıktısı bu testlerin hiçbirinin yerine geçmez.