DDD'yi uygulama: kullanıcılar ve izinler


16

Etki alanı odaklı tasarım ilkelerini kavramaya çalışan küçük bir uygulama üzerinde çalışıyorum. Başarılı olursa, bu daha büyük bir proje için bir pilot olabilir. "Etki Alanına Dayalı Tasarımın Uygulanması" (Vaughn Vernon tarafından) kitabını takip etmeye ve benzer, basit bir tartışma forumu uygulamaya çalışıyorum. Ben de github IDDD örnekleri kontrol ettik. Davam için Kimlik ve Erişimi kabul etmekte bazı zorluklar yaşıyorum. Arka plan bilgisi vereyim:

  • (Umarım) kullanıcıları ve izinler mantığını ayırmanın ardındaki mantığı anlıyorum: destekleyici bir alan ve farklı sınırlı bir bağlam.
  • Çekirdek etki alanında kullanıcı yok, yalnızca Yazarlar, Moderatörler vb. Var. Bunlar, bir hizmet kullanarak Kimlik ve Erişim bağlamına ulaşarak ve sonra alınan Kullanıcı nesnelerini ve Moderatöre çevirerek oluşturulur.
  • Etki alanı işlemleri parametre olarak ilgili bir rolle çağrılır: örn:

    ModeratePost( ..., moderator);

  • Etki alanı nesnesinin yöntemi, verilen Moderator örneğinin null olup olmadığını denetler (Kimlik ve Erişim bağlamından istenen kullanıcının Moderatör rolü yoksa Moderator örneği null olur).

  • Bir durumda, bir Gönderiyi değiştirmeden önce ek bir kontrol yapar:

    if (forum.IsModeratedby(moderator))

Sorularım:

  • İkinci durumda, güvenlik kaygıları tekrar temel etki alanına karışmıyor mu? Daha önce kitaplar, "bir konuyu kimin gönderebileceği ya da izin verilen koşullar altında. Bir Forumun şu anda bir Yazarın bunu yaptığını bilmesi gerekiyor" demektedir.

  • Kitaptaki role dayalı uygulama oldukça basittir: Bir Moderatör temel etki alanı olduğunda, mevcut userId'yi bir Moderator örneğine veya gerektiğinde bir Yazara dönüştürmeye çalışır. Kullanıcı uygun role sahip değilse hizmet uygun örneğe veya null değerine yanıt verecektir. Ancak bunu daha karmaşık bir güvenlik modeline nasıl adapte edebileceğimi göremiyorum; pilotluk yaptığım şu anki projemizde gruplar, EKL'ler vb. içeren oldukça karmaşık bir model var.

Çok karmaşık olmayan kurallarda bile: "Bir gönderi yalnızca Sahibi veya Editör tarafından düzenlenmelidir", bu yaklaşım bozulur veya en azından onu uygulamak için doğru yolu göremiyorum.

Bir OwnerOrEditor örneği için Kimlik ve Erişim bağlamını sormak doğru gelmiyor ve çekirdek etki alanında giderek daha fazla güvenlikle ilgili sınıflarla karşılaşıyorum. Buna ek olarak, sadece userId değil, korunan kaynağın (yazı, forum vb. Kimliği) güvenlik bağlamına geçmesi gerekirdi, muhtemelen bu şeyleri önemsememelidir (doğru mu? )

Çekirdek etki alanına izinleri alarak ve etki alanı nesnelerinin yöntemlerinde veya hizmetlerinde denetleyerek, birinci kareye geliyorum: güvenlik endişelerini etki alanı ile karıştırmak.

Güvenlik ve izinler temel etki alanı değilse, bir yerde okudum (ve kabul ediyorum) bu izinle ilgili şeylerin temel etki alanının bir parçası olmaması gerekir. Yukarıda verilen gibi basit bir kural, güvenliği temel alanın bir parçası haline getirmeyi haklı çıkarıyor mu?


Belki de burada neye ihtiyacınız olduğunu bulabilirsiniz: stackoverflow.com/a/23485141/329660 Ayrıca, Erişim Denetimi bağlamının bir kaynak kimliği hakkında bilgi sahibi olması, kaynağın ne tür bir varlık veya ne olduğu hakkında etki alanı bilgisine sahip olduğu anlamına gelmez. yapar.
guillaume31

Teşekkürler, bu gönderiyi daha önce gördüm, sorunum tam olarak düzenlemenin sonunda söylediği şey: Erişim kontrolünü çekirdek alanımın dışına taşımak istiyorum, ancak uygulamamla bir duvara çarptığımı hissediyorum. Bununla birlikte, kaynak kimliği hakkındaki öneriniz mantıklıdır: Temel etki alanında Kullanıcı veya Rol kavramını değil, somut rolleri kullanmadığım için belki de BC güvenliğindeki Kaynak kavramını kullanabilir ve ilgili betonla eşleyebilirim etki alanı kavramı. Denemeye değer, teşekkürler!
LittlePilgrim

Bağlantıdaki kod örnekleri en azından "Bunu daha karmaşık bir güvenlik modeline nasıl uyarlayabilirim" şeklinde yanıtlamıyor mu?
guillaume31

Benim sorunum güvenlik modelinin kendisinin uygulanmasıyla ilgili değil, bu daha karmaşık kuralları etki alanı ile nasıl eşleştirmem gerektiğini göremiyorum. Güvenlik tarafında basit bir rol tabanlı model değilse Kullanıcı -> Yazar eşlemesi nasıl değişmelidir? Kaynak kimliklerini diğer bağlama geçirme gibi olabilir, HasPermissionToEdit(userId, resourceId)ancak etki alanı mantığını bu çağrılarla kirletme hakkını hissetmiyorum. Etki alanı mantığını çağırmadan önce, muhtemelen uygulama hizmeti yöntemlerinde bu kontrol etmeliyim?
LittlePilgrim

Tabii ki uygulama hizmetlerinde olmalı ... UserService @AccessControlList[inf3rno]Ben bağlantılı cevap gibi kod bölümlerinden net olduğunu düşündüm .
guillaume31

Yanıtlar:


6

Gerçek erişim kontrol kuralları ile erişim kontrolünde sınır çizgisi olan alan değişmezleri arasında ayrım yapmak bazen zor olabilir.

Özellikle, yalnızca belirli bir etki alanı mantığı parçasına kadar olan verilere bağlı olan kurallar, etki alanından kolayca çıkarılamaz. Erişim Denetimi genellikle bir etki alanı işlemi gerçekleştirilmeden önce veya sonra çağrılır, ancak sırasında çağrılmaz.

Vaughn Vernon assert (forum.IsModeratedBy(moderator))örneği muhtemelen Alan adının dışında olmalıdır, ancak her zaman mümkün değildir.

Ben sadece userId değil, muhtemelen bu şeyler (bu doğru mu?

Bir Güvenlik BC'si varsa ve bu mantığı işlemesini istiyorsanız, bir Forumun ayrıntılı olarak ne olduğunu bilmek zorunda değildir, ancak:

  • Sadece "yöneten" gibi kavramlar hakkında bilgi sahibi olabilir ve buna göre erişim hakları verebilir veya reddedebilir.
  • Çekirdek Etki Alanı olaylarına abone olan ve bunları Güvenlik BC'nin depolaması ve kullanması için basit (kaynak, yetkili kullanıcı) anahtar değeri çiftlerine çeviren bağdaştırıcı mantığınız olabilir.

Her iki cevap da faydalı olduğundan ve aşağı yukarı aynı yöne işaret ettiğinden ikisini de iptal ettim. @ Guillaume31 Vernon'un uygulanmasıyla ilgili sorumu az çok cevapladığı için bunu kabul ettim ve MÖ Güvenlik'te kaynakları kullanma ipucuna dayanarak uygulamaya devam edeceğim.
LittlePilgrim

Bunu cevabımın tam tersinde düşündüğümü söylemeliyim.
Ewan

1
Belki şu ana kadar çok kafam karıştı, ama benim yorumum (her iki cevap için): 1. Güvenlikle ilgili endişeleri etki alanından uzak tutun ve güvenliği BC'yi bir hizmet olarak kullanın 2. Herhangi bir etki alanı nesnesini çağırmadan önce hizmeti arayın 3. Hizmet moderator = securityService.GetModerator(userId, forumId) 4. kullanıcılardan / işlemlerden moderatörlere, yazarlara vb . eşleme yapacaktır. 4. Etki alanı mantığı moderator.EditPost () gibi bu nesnelerde uygulanacaktır. EditPost gibi yöntemler güvenlik kavramları hakkında hiçbir şey bilmeyecek, ek kontroller olmayacaktır. orada
LittlePilgrim

Bu konuda hala cevaplar / yön arıyorum, ancak nesnenin mevcut durumuna dayanan herhangi bir yetkilendirme mantığının (şu anda bir moderatöre atanmış gibi) aslında ait olduğu iş mantığı olduğunu buldum ve alan adınızda değilse, modelin aynı anda güncellenebilmesi durumunda geçersiz duruma geçme riskiniz olabilir. Örneğin, bir ilkeyi kullanarak sahipliği doğrular ve ardından bu nesneyi güncellemeye devam ederseniz - birçok alanda sahipliğin değişebileceği ve işlem artık geçerli olmayabilir.
Ürdün

Çok karmaşık bir işbirlikçi bağlamınız olmadığı sürece, burada sürüm oluşturmayı kullanarak iyimser bir eşzamanlılık modeli uygulamayı göze alamazsanız, ancak kontrolleriniz belirli bir toplu örnek içinde veya en azından buna karşı yapılmazsa, çekleriniz gerçekle tutarlı olmayabilir Değişikliklerinizi sürdürdüğünüz zaman nesnenin durumu.
Ürdün

5

Kimlik Doğrulama ve Yetkilendirme DDD için kötü bir örnektir.

Şirketiniz güvenlik ürünleri oluşturmadığı sürece bunların hiçbiri bir Alanın parçası değildir.

İşletme veya alan adı gereksinimi "Role dayalı kimlik doğrulaması istiyorum" olmalıdır veya olmalıdır

Daha sonra bir etki alanı işlevini çağırmadan önce rolü kontrol edersiniz.

'Kendi gönderilerimi düzenleyebilirim ancak başkalarını değil' gibi karmaşık gereksinimleriniz varsa, alan adınızın düzenleme işlevini ayırdığından emin olun EditOwnPost()ve EditOthersPost()böylece rol eşlemesi için basit bir işleve sahip olun.

Ayrıca , yönteminizin bir Etki Alanı Hizmetinde mi yoksa bir Etki Alanı Nesnesinde mi olduğuna bağlı olarak, işlevselliği Etki Alanı Nesneleri gibi ayırtabilirsiniz Poster.EditPost()ve Moderator.EditPost()bu daha OOP yaklaşımıdır.

Ancak, Rol eşlemesinin Etki Alanı dışında gerçekleşeceği kodu ayırmayı seçersiniz. örneğin bir webapi denetleyiciniz varsa:

PostController : ApiController
{
    [Authorize(Roles = "User")]
    public void EditOwnPost(string postId, string newContent)
    {
        this.postDomainService.EditOwnPost(postId, string newContent);
    }

    [Authorize(Roles = "Moderator")]
    public void EditOtherPost(string postId, string newContent)
    {
        this.postDomainService.EditOtherPost(postId, string newContent);
    }
}

Rol eşlemesinin barındırma katmanında yapılmasına rağmen, kendi veya başka bir postayı düzenlemenin neyin karmaşık mantığı alan adının bir parçasıdır.

Etki alanı eylemlerin farkını tanır, ancak güvenlik gereksinimi basitçe "işlevsellik rollerle sınırlanabilir" dir .

Bu belki de etki alanı nesnelerinin ayrılmasıyla daha açıktır, ancak aslında hizmet yöntemini çağıran yöntem yerine nesneyi oluşturan yöntemi kontrol edersiniz. İhtiyacınız, hala etki alanının bir parçası olarak seslendirmek istiyorsanız 'yalnızca moderatörler moderatör nesnesini oluşturabilir'


4
Rolü "statik olarak" kontrol etmek biraz basittir. Bir moderatörün başka bir moderatörün yayınını düzenlemesine izin verilmezse ne olur? Bu kontrol alan adının bir parçası olmamalı mı?
Réda Housni Alaoui

2
@ RédaHousniAlaoui Bunu da merak ediyorum. Ben bu etki alanı ya Kullanıcılar / Moderatörler bazı söz dahil veya yazıcının yazar rolünü almak için bu ApiController içinde bir tür mantık gerçekleştirmek dışında bir yolu düşünemiyorum. Bunların hiçbiri doğru görünmüyor ve bu benim deneyimimde bazı açık rehberliklerin son derece yararlı olacağı kadar yaygın bir şey.
Jimmy

1
@Erwan, bahsettiğim kullanım örneği dinamik. "Doğrulama ve Yetkilendirme DDD için kötü bir örnektir" cümlesini merhaba dünya örneklerine dayandırmak sahtekârlıktır. DDD, yanlışlıkla karmaşıklığı önlemek ve alan karmaşıklığını yönetmeye izin vermek için burada. Dinamik izinler tesadüfi bir karmaşıklık veya gerçek hayatta olmayan bir şey değildir.
Réda Housni Alaoui

1
IMHO, çözümünüzün sorunu müşteriyi tatmin etmemesi. Müşteri genellikle bu ilişkileri dinamik olarak değiştirmek ister. Ayrıca, bir satıcı farklı şirketlere aynı kurumsal yazılımı sağladığında da olan budur. Yazılım zayıf ayarlanabiliyorsa, satıcı sonunda ölecektir.
Réda Housni Alaoui

1
"Ancak, güvenlik ayarlarınızın zaman içinde yönetilemez hale gelmesi genellikle" kötü bir şey "olarak kabul edilir, bu da uygulamanızın güvensiz hale geldiği anlamına gelir." Doğru tasarım ve test ile tamamen yönetilebilir. Ancak, XP'mden doğru tasarımı üretmek için etki alanının izni kontrol etmesi gerekir. Alternatif ütopyadır.
Réda Housni Alaoui
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.