özet
CQRS / DDD'de yetkilendirme komut başına / sorgu başına uygulanmalı mı, uygulanmamalı mı?
DDD CQRS modelini az çok kesinlikle kullanarak çevrimiçi bir uygulama geliştiriyorum. Başımı gerçekten alamadığım bir problemle karşılaştım.
Oluşturduğum uygulama, insanların defter oluşturmasına izin veren ve diğer kişilerin çalışanlar gibi onları görüntülemesine / düzenlemesine / silmesine izin veren bir defter uygulamasıdır. Bir defteri kuranın yaratıcısı, oluşturduğu deftere erişim haklarını düzenleyebilmelidir. Sahipliği bile değiştirebilir. Etki alanının iki toplamı TLedger ve TUser'dir .
O yetki bir oldu belirtti vb DDD / CQRS anahtar kelime ile ilgili güvenlik, yetkilendirme, Bunların çoğu ile mesajların çok okumak Jenerik Altalan bir güvenlik uygulaması oluşturmadan sürece,.
Bu durumda, temel etki alanı kesinlikle işlemler, dengeleme ve hesaplarla ilgilenen bir muhasebe alanıdır . Ancak defterlere ince taneli erişimi yönetebilme işlevselliği de gereklidir. Bunu DDD / CQRS açısından nasıl tasarlayacağımı merak ediyorum.
Her yerde DDD eğitimlerinde komutların her yerde bulunan dilin bir parçası olduğu belirtiliyor. Anlamlılar. Bunlar "gerçek şeyi" temsil eden somut eylemlerdir.
Tüm bu komutlar ve sorgular, kullanıcıların "gerçek hayatta" gerçekleştireceği gerçek eylemler olduğundan, yetkilendirmenin uygulanması tüm bu "komutlar" ve "sorgular" ile birleştirilmeli mi? Bir kullanıcının örneğin TLedger.addTransaction () yürütme yetkisi vardır, ancak TLedger.removeTransaction () yöntemini kullanmaz. Veya bir kullanıcının "getSummaries ()" sorgusunu yürütmesine izin verilir, ancak "getTransactions ()" sorgusunu yürütmesine izin verilmez.
Erişim haklarını belirlemek için kullanıcı defteri-komutu veya kullanıcı defteri defteri sorgusu şeklinde üç boyutlu bir eşleme bulunacaktır.
Veya, ayrıştırılmış bir şekilde, "izinler" adlı bir kullanıcı için kaydedilir. Daha sonra belirli komutlar için eşlenecek izinler. Örneğin, "ManageTransactions" izni, bir kullanıcının "AddTransaction ()", "RemoveTransaction ()" vb. Yürütmesine izin verir.
İzin eşleme kullanıcısı -> defter -> komut / sorgu
İzin eşleme kullanıcısı -> defter -> izin -> komut / sorgu
Sorunun ilk kısmı bu. Veya kısaca, komut başına veya sorgu başına CQRS / DDD yetkisi uygulanmalı mıdır? Veya yetkilendirme komutlardan ayrılmalıdır mı?
İkincisi, izinlere dayalı yetkilendirme ile ilgili. Bir Kullanıcı, Defterleri veya yönetmesine izin verilen Defterler üzerindeki izinleri yönetebilmelidir.
- Yetkilendirme yönetimi komutları Defter'de gerçekleşir
Olayları / komutları / işleyicileri grantPermission (), revokePermission (), vb. Gibi Ledger toplamına eklemeyi düşündüm. Bu durumda, bu kuralların uygulanması komut işleyicilerine gerçekleşir. Ancak bu, tüm komutların söz konusu komutu yayınlayan kullanıcının kimliğini içermesini gerektirir. Sonra o kullanıcının bu komutu yürütmesine izin verilip verilmediğini TLedger'a kontrol ederim.
Örneğin :
class TLedger{
function addTransactionCmdHandler(cmd){
if (!this.permissions.exist(user, 'addTransaction')
throw new Error('Not Authorized');
}
}
- Kullanıcıdaki yetkilendirme yönetimi komutları
Bunun diğer yolu izinleri TUser'e dahil etmek olacaktır. Bir TUser'in bir dizi izinleri olurdu. Sonra, TLedger komut işleyicilerinde, kullanıcıyı alıp komutu yürütme iznine sahip olup olmadığını kontrol ederdim. Ancak bu, her TLedger komutu için TUser toplamını getirmemi gerektiriyor.
class TAddTransactionCmdHandler(cmd) {
this.userRepository.find(cmd.userId)
.then(function(user){
if (!user.can(cmd)){
throw new Error('Not authorized');
}
return this.ledgerRepository.find(cmd.ledgerId);
})
.then(function(ledger){
ledger.addTransaction(cmd);
})
}
- Hizmete sahip başka bir alan adı
Başka bir olasılık, başka bir yetkilendirme alanını tamamen modellemek olacaktır. Bu alan adı erişim hakları, yetkilendirme vb. İle ilgilenecektir. Daha sonra muhasebe alt alanı, bu yetkilendirme alanına erişmek için bir hizmet kullanır AuthorizationService.isAuthorized(user, command)
.
class TAddTransactionCmdHandler(cmd) {
authService.isAuthorized(cmd)
.then(function(authorized){
if (!authorized) throw new Error('Not authorized');
return this.ledgerRepository.find(cmd.ledgerId)
})
.then(function(){
ledger.addTransaction(cmd);
})
}
Hangi karar en "DDD / CQRS" yoludur?