İçeriğe geç
Çılgın Yazılım

Kurumsal Yazılım ve Entegrasyon kod örnekli

Kurumsal Yazılımda Yetkilendirme Modelini Baştan Doğru Kurmak

Rol sayısı otuza çıktıysa ve kimse kimin neye eriştiğini bilmiyorsa, sorun yetki listesinde değil modeldedir.

Çılgın Yazılım 4 dk okuma

Kurumsal Yazılımda Yetkilendirme Modelini Baştan Doğru Kurmak
İçindekiler
  1. Rol patlamasının sebebi: rolle izni karıştırmak
  2. İkinci ve daha kritik soru: kapsam
  3. Hiyerarşi ve devralma
  4. Çok kiracılı yapılarda ek katman
  5. Denetlenebilirlik: kim, neye, ne zaman erişti?
  6. Sonradan düzeltmek: nereden başlamalı?
  7. Sonuç

Yetkilendirme modeli, kurumsal yazılımlarda en erken kurulması gereken ama genellikle en geç düşünülen katmandır. Proje başlarken iki rol vardır: yönetici ve kullanıcı. Bir yıl sonra rol sayısı otuz olmuştur, her yeni müşteri talebi yeni bir rol doğurmuştur ve kimse "bölge müdürü yardımcısı (kıdemli)" rolünün tam olarak neye eriştiğini söyleyemez. Bu noktada sorun izin listesinde değil, modelin kendisindedir.

Yetkilendirme katmanları diyagramı
İzin kontrolü tek başına yeterli değildir; kayıt kapsamı ayrı bir sorudur.

Rol patlamasının sebebi: rolle izni karıştırmak

En yaygın tasarım hatası, yetki kontrollerini doğrudan rol adına bakarak yapmaktır:

Kod
// Kırılgan: her yeni rol, bu satırların hepsini gözden geçirmeyi gerektirir
if ($kullanici->rol === 'yonetici' || $kullanici->rol === 'muhasebe_sefi') {
    // faturayı onayla
}

Bu yaklaşımda her yeni rol, kod tabanındaki onlarca koşulun tekrar elden geçirilmesini gerektirir. Ve bu gözden geçirme eksik yapıldığında, yeni rol ya yapması gereken işi yapamaz ya da yapmaması gereken bir işe erişir.

Doğru yapı, araya bir katman koyar: roller izinleri taşır, kod ise izinleri kontrol eder.

Kod
// Sağlam: yeni rol eklemek kod değişikliği gerektirmez
if ($kullanici->izinVarMi('fatura.onayla')) {
    // faturayı onayla
}

Bu ayrım sayesinde yeni bir rol tanımlamak, yalnızca hangi izinlere sahip olacağını işaretlemek anlamına gelir. Kod hiç değişmez ve yetki matrisi yönetim ekranından okunabilir hâle gelir.

İkinci ve daha kritik soru: kapsam

Yetkilendirmenin en sık atlanan tarafı budur. "Bu kullanıcı fatura görüntüleyebilir mi?" ile "bu kullanıcı bu faturayı görüntüleyebilir mi?" farklı sorulardır. Yalnızca ilkini kontrol eden bir sistemde, geçerli izne sahip bir kullanıcı adres çubuğundaki kimlik numarasını değiştirerek başka bir şirketin veya başka bir bölgenin kaydını görebilir. Bu, en yaygın kritik güvenlik açıklarından biridir (IDOR).

Doğru yaklaşım, kapsam kontrolünü isteğe bağlı bir ek kontrol olarak değil, sorgunun kendisine gömülü bir kısıt olarak kurmaktır:

Kod
// Kayıt önce çekilip sonra kontrol edilmez; sorgu zaten kapsamla sınırlıdır
$fatura = $faturaModel
    ->where('sirket_id', $kullanici->sirketId)
    ->find($id);

if (! $fatura) {
    throw new NotFoundException();  // yetkisiz erişim "bulunamadı" gibi görünür
}

Kapsamı sorguya gömmek, geliştiricinin unutması durumunda bile varsayılan olarak güvenli davranış üretir. Bunu daha da sağlamlaştırmak için model katmanında otomatik uygulanan bir kapsam filtresi (global scope) kurmak, büyük kod tabanlarında en dayanıklı çözümdür.

Hiyerarşi ve devralma

Kurumsal yapılarda erişim genellikle organizasyon şemasını izler: bir bölge müdürü, altındaki tüm şubelerin kayıtlarını görmelidir. Bu ihtiyaç iki şekilde çözülür. Basit hiyerarşilerde, kullanıcının erişebileceği birim kimliklerini bir ağaç sorgusuyla hesaplayıp sorguya whereIn olarak eklemek yeterlidir. Derin ve sık değişen hiyerarşilerde ise erişilebilir birimleri önceden hesaplayıp bir tabloda tutmak (materyalize etmek), her istekte ağaç dolaşmanın maliyetini ortadan kaldırır.

Burada dikkat edilmesi gereken nokta, devralmanın varsayılan olup olmayacağıdır. Bazı veriler (maaş bilgisi gibi) hiyerarşi yukarı doğru otomatik akmamalıdır. Bu yüzden devralmanın veri türüne göre açıkça tanımlanması gerekir.

Çok kiracılı yapılarda ek katman

Birden fazla müşteri kurumun aynı sistemde barındığı yapılarda kiracı ayrımı, diğer tüm yetki kontrollerinden önce gelir ve asla atlanmamalıdır. Buradaki en güvenli tasarım, kiracı kimliğinin istekten değil, oturumdan alınması ve veritabanı katmanında zorunlu bir filtre olarak uygulanmasıdır. İstekten gelen bir kiracı parametresine güvenmek, tek bir unutulmuş kontrolde tüm müşteri verilerinin karışmasına yol açabilir.

Denetlenebilirlik: kim, neye, ne zaman erişti?

Kurumsal müşterilerin er ya da geç soracağı soru budur ve sonradan eklenmesi en zor özelliktir. Yetki değişikliklerinin (kim hangi role hangi izni verdi) ve hassas kayıtlara erişimin kaydedilmesi, hem uyum gereksinimlerini karşılar hem de bir olay sonrası inceleme imkânı verir. Bu kayıtların değiştirilemez olması ve normal uygulama log'larından ayrı tutulması önemlidir; log içeriğini planlarken log yazma rehberimize bakabilirsiniz.

Sonradan düzeltmek: nereden başlamalı?

Model zaten bozuksa, her şeyi durdurup yeniden yazmak gerekmez. İşleyen sıra şudur: önce mevcut rollerin gerçek izin matrisini çıkarın (çoğu ekip bunu ilk kez yaptığında sürprizlerle karşılaşır), ardından kod içindeki rol adı kontrollerini izin kontrollerine çevirin, sonra en hassas modülden başlayarak kapsam filtrelerini sorgulara gömün. Bu kademeli geçiş, büyük patlama göçünden kaçınma ilkeleriyle aynı mantığı izler. Erişim kontrolü tasarımının güvenlik tarafındaki genel çerçevesi için OWASP Top Ten ve mimari yaklaşımlar için sıfır güven mimarisi yazımız ilgili kaynaklardır.

Sonuç

İyi bir yetkilendirme modeli iki soruyu ayrı ayrı ve tutarlı biçimde cevaplar: kullanıcı bu işlemi yapabilir mi, ve bu kayda erişebilir mi? Rol adına bakan kontroller birinci soruyu kırılgan biçimde, kapsamsız sorgular ise ikinci soruyu hiç cevaplamaz. Rolleri izin taşıyıcısına dönüştürmek ve kapsam kısıtını sorgunun içine gömmek, sonradan eklenmesi çok pahalı olan iki tasarım kararıdır. Projenizde hızlı bir sınama yapın: bir kullanıcının erişemeyeceği bir kaydın kimliğini adres çubuğuna yazın. "Bulunamadı" yerine kaydı görüyorsanız, kapatılması gereken bir açığınız var demektir.

Beğeniniz benzer içerikleri öne çıkarmamıza yardımcı olur.

Sık sorulan sorular

Kaç rol makul sayılır?

Sabit bir sayı yoktur, ancak roller izin taşıyıcısı olarak tasarlandığında rol sayısı sorun olmaktan çıkar. Rol sayısının rahatsız edici hâle gelmesi, genellikle kodun rol adına bakıyor olmasının belirtisidir.

İzinleri veritabanında mı, kodda mı tanımlamalıyım?

İzin listesinin kendisi (hangi izinler var) kodda tanımlanmalı ki sürüm kontrolüyle takip edilsin; rollere atanması ise veritabanında olmalı ki çalışma anında yönetilebilsin.

Kapsam kontrolünü her sorguya eklemek yorucu değil mi?

Elle eklendiğinde evet ve bu yüzden unutulur. Model katmanında otomatik uygulanan bir kapsam filtresi kurmak, hem yükü kaldırır hem de varsayılan davranışı güvenli hâle getirir.

Süper yönetici rolü tehlikeli mi?

Gerekli ama sınırlandırılmalıdır. Bu rolün kullanımının kayıt altına alınması, mümkünse geçici olarak yükseltilmesi ve günlük işlerde kullanılmaması iyi bir pratiktir.

Yazan

Çılgın Yazılım

Ben Evren Çılgın; yazılım geliştirme, web teknolojileri ve sistem tasarımı alanlarında uzmanlaşmış bir geliştiriciyim. Uzun yıllardır hem frontend hem de backend tarafında üretken, ölçeklenebilir ve kullanıcı dostu çözümler üretiyorum.

Hakkımızda Bize ulaşın

Bu konuda bir projeniz mi var?

İhtiyacınızı birkaç cümleyle anlatın; uygun yaklaşımı birlikte belirleyelim.

Projenizi Anlatın

İlgili yazılar

Yorumlar

Henüz yorum yok. Sorunuzu ya da deneyiminizi ilk siz yazın.

Yorum yazın

Yorumunuz onaylandıktan sonra yayınlanır. Ekibimiz gerekirse konuyla ilgili bir yanıt da paylaşır.

Yayınlanmaz; yalnızca gerektiğinde size ulaşmak için.

En az 10 karakter.

Tüm yazılar