Mert Özen Her Satırda Daha İleri
Backend .NET Core Web API — #21

Role ve policy tabanlı yetkilendirme: Kime neyin izinli olduğunu belirlemek

Mert Özen 15 Ağu 2026 13 dk 21 görüntülenme
Role ve policy tabanlı yetkilendirme: Kime neyin izinli olduğunu belirlemek

Yetkilendirmeyi derinleştiriyoruz: rol tabanlı yetki nedir, nerede yetersiz kalır, policy ve claim tabanlı yaklaşım nasıl daha esnek çözüm sunar ve .NET'te bunları nasıl kurarız?

Önceki yazıda kullanıcının kimliğini JWT ile doğruladık ve token'ın içine bir "rol" bilgisi koyduk. On dokuzuncu yazıda ise [Authorize(Roles = "Admin")] ile kısa bir yetki örneği görmüştük. Bugün o parçaları birleştirip yetkilendirmeyi ciddi biçimde ele alıyoruz. İki temel yaklaşımı konuşacağız: rol tabanlı ve policy tabanlı. İkisi de "kim neye erişebilir?" sorusuna cevap verir ama farklı esneklik seviyelerinde.

Rol Tabanlı Yetkilendirme

En basit ve en yaygın yaklaşım bu. Kullanıcıları rollere ayırırsın: Admin, Editor, User gibi. Sonra her endpoint'in hangi role açık olduğunu belirtirsin. Token içindeki rol bilgisi, on dokuzuncu yazıda gördüğümüz claim'lerden biriydi; işte yetkilendirme tam da bu bilgiyi kullanır.

[HttpDelete("{id}")]
[Authorize(Roles = "Admin")]
public IActionResult Delete(int id)
{
    return Ok($"{id} numaralı kayıt silindi.");
}

Bu endpoint sadece "Admin" rolüne sahip kullanıcılara açık. Kimliği doğrulanmış ama Admin olmayan biri gelirse, on dokuzuncu yazıda konuştuğumuz gibi 403 Forbidden alır. Birden fazla role izin vermek de mümkün; rolleri virgülle ayırırsın:

[Authorize(Roles = "Admin,Editor")]

Bu durumda hem Admin hem de Editor rolündeki kullanıcılar erişebilir. Rol tabanlı yaklaşım sezgiseldir, okunması kolaydır ve çoğu uygulamanın ihtiyacını karşılar. "Yöneticiler silebilir, editörler düzenleyebilir, kullanıcılar okuyabilir" gibi net ayrımlar için biçilmiş kaftandır.

Rol Tabanlı Yaklaşım Nerede Yetersiz Kalıyor?

Roller basit senaryolarda harika ama gerçek dünya çoğu zaman daha karmaşık. Diyelim ki kuralın şu: "Bir kullanıcı yalnızca 18 yaşından büyükse şu içeriğe erişebilir." Ya da "Sadece premium abonelik sahibi kullanıcılar bu özelliği kullanabilir." Bunlar bir role sığmaz; bir role değil, kullanıcının belirli bir özelliğine bakan kurallardır.

Rolle her şeyi çözmeye çalışırsan, rol adları çığırından çıkar: "Admin", "AdminOver18", "PremiumEditor" gibi tuhaf birleşimler türetmeye başlarsın. Bu, yönetilemez bir karmaşaya yol açar. İşte tam bu noktada daha güçlü bir araç devreye girer: policy tabanlı yetkilendirme.

Policy Tabanlı Yetkilendirme

Policy, bir yetki kuralına isim verip onu tek bir yerde tanımlama fikridir. "Rol Admin olmalı" gibi basit bir kuralı değil, "kullanıcının yaşı 18'den büyük olmalı" gibi herhangi bir mantığı bir policy'ye koyabilirsin. Sonra endpoint'lerde bu policy'nin adını kullanırsın. Kuralın kendisi bir yerde durur, endpoint'ler ise sadece adına referans verir.

Bir policy'yi Program.cs'te tanımlarsın. Basit bir örnek, "en az 18 yaşında olma" kuralını içeren bir policy:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("Over18", policy =>
        policy.RequireClaim("Age", "18", "19", "20", "21"));
});

Bu policy, token içinde "Age" claim'ine bakar ve belirli değerlerden birini taşıyorsa izin verir. Gerçek projelerde bu kuralı daha esnek yazmanın yolları var (bir yaş aralığını tek tek saymak yerine), ama mantığı görmen için bu örnek yeterli. Artık bu policy'yi bir endpoint'e uygulayabilirsin:

[HttpGet("adult-content")]
[Authorize(Policy = "Over18")]
public IActionResult GetAdultContent()
{
    return Ok("Bu içerik yalnızca 18 yaş üstü kullanıcılara açıktır.");
}

Dikkat et: attribute artık Roles değil, Policy alıyor. Kuralın kendisi endpoint'te değil, Program.cs'teki tanımda yaşıyor. Bu ayrım güçlü bir avantaj getirir: aynı policy'yi onlarca endpoint'te kullanabilir, kuralı değiştirmen gerektiğinde ise tek bir yeri düzeltirsin. Rol tabanlı yaklaşımda kural endpoint'e gömülüyken, policy'de kural merkezileşir.

Claim Tabanlı Düşünmek

Policy'lerin arkasındaki asıl fikir claim'lerdir. Yirminci yazıda claim'leri, token içinde taşınan kullanıcı bilgileri olarak tanımlamıştık: adı, rolü, belki yaşı, abonelik durumu. Aslında rol bile bir claim türüdür; sadece özel olarak "rol" diye adlandırılmış bir bilgidir.

Bu bakış açısı önemli çünkü seni daha esnek düşünmeye iter. "Bu kullanıcı hangi rolde?" diye sormak yerine, "bu kullanıcı hangi özelliklere sahip?" diye sorarsın. Yaşı, ülkesi, abonelik seviyesi, hesabının doğrulanmış olup olmadığı... Bunların hepsi birer claim olabilir ve policy'ler bu claim'lere dayanarak karar verir. Roller bu resmin sadece bir parçasıdır; claim'ler ise tüm resmi görmeni sağlar.

Peki Hangisini Seçmeliyim?

İkisi birbirinin rakibi değil, tamamlayıcısı. Basit ve net yetki ayrımları için rol tabanlı yaklaşım fazlasıyla yeterli ve okunması en kolay olan budur; "yönetici / editör / kullanıcı" gibi klasik ayrımlarda doğrudan rol kullan. Kuralın bir role sığmıyorsa, kullanıcının belirli bir özelliğine (yaş, abonelik, konum gibi) bakıyorsa ya da aynı kuralı birçok yerde tekrar kullanacaksan, policy'ye geç.