Saya sedang mengerjakan aplikasi kecil yang mencoba memahami prinsip-prinsip desain berbasis domain. Jika berhasil, ini mungkin menjadi pilot untuk proyek yang lebih besar. Saya mencoba mengikuti buku "Menerapkan Desain Berbasis Domain" (oleh Vaughn Vernon) dan mencoba menerapkan forum diskusi yang serupa dan sederhana. Saya juga sudah memeriksa sampel IDDD di github. Saya mengalami beberapa kesulitan dalam mengadopsi Identitas dan Akses ke kasus saya. Biarkan saya memberikan beberapa informasi latar belakang:
- Saya (semoga) memahami alasan di balik pemisahan antara pengguna dan logika izin: ini adalah domain pendukung, dan ini merupakan konteks terikat yang berbeda.
- Dalam domain inti, tidak ada pengguna, hanya Penulis, Moderator, dll. Ini dibuat dengan menjangkau konteks Identitas dan Akses menggunakan layanan dan kemudian menerjemahkan objek Pengguna yang diterima ke dan Moderator.
Operasi domain dipanggil dengan peran terkait sebagai parameter: misalnya:
ModeratePost( ..., moderator);
Metode objek domain memeriksa jika turunan Moderator yang diberikan bukan nol (turunan Moderator akan menjadi nol jika pengguna bertanya dari konteks Identity and Access tidak memiliki peran Moderator).
Dalam satu kasus, ia melakukan pemeriksaan tambahan sebelum mengubah sebuah Posting:
if (forum.IsModeratedby(moderator))
Pertanyaan saya adalah:
Dalam kasus terakhir, bukankah masalah keamanan dicampur lagi ke dalam domain inti? Sebelumnya buku-buku menyatakan "dengan siapa yang dapat memposting subjek, atau dalam kondisi apa yang diizinkan. Forum hanya perlu tahu bahwa seorang Penulis melakukan itu sekarang".
Implementasi berbasis peran dalam buku ini cukup mudah: ketika seorang Moderator adalah domain inti mencoba untuk mengubah userId saat ini menjadi instance Moderator atau menjadi seorang Penulis ketika diperlukan. Layanan akan merespons dengan contoh yang sesuai atau nol jika pengguna tidak memiliki peran yang diperlukan. Namun, saya tidak bisa melihat bagaimana saya bisa mengadaptasi ini ke model keamanan yang lebih kompleks; proyek kami saat ini yang saya uji coba memiliki model yang agak rumit dengan grup, ACL, dll.
Bahkan dengan aturan yang tidak terlalu rumit, seperti: "Sebuah posting harus diedit hanya oleh Pemilik atau Editornya", pendekatan ini tampaknya rusak, atau setidaknya saya tidak melihat cara yang benar untuk mengimplementasikannya.
Dengan menanyakan konteks Identitas dan Akses untuk instance OwnerOrEditor tidak terasa benar, dan saya akan berakhir dengan semakin banyak kelas terkait keamanan di domain inti. Selain itu, saya harus lulus tidak hanya userId, tetapi pengidentifikasi sumber daya yang dilindungi (id posting, forum, dll.) Ke konteks keamanan, yang mungkin seharusnya tidak peduli tentang hal-hal ini (apakah benar? )
Dengan menarik izin ke domain inti dan memeriksanya dalam metode objek domain atau dalam layanan, saya akan berakhir di titik awal: mencampur masalah keamanan dengan domain.
Saya sudah membaca di suatu tempat (dan saya cenderung setuju dengan itu) bahwa hal-hal yang terkait dengan izin ini seharusnya tidak menjadi bagian dari domain inti, kecuali keamanan dan izin adalah domain inti itu sendiri. Apakah aturan sederhana seperti yang diberikan di atas membenarkan menjadikan keamanan sebagai bagian dari domain inti?
sumber
HasPermissionToEdit(userId, resourceId)
tapi saya merasa tidak benar untuk mencemari logika domain dengan panggilan ini. Mungkin saya harus memeriksa ini dalam metode layanan aplikasi, sebelum memohon logika domain?UserService @AccessControlList[inf3rno]
pada jawaban yang saya tautkan.Jawaban:
Terkadang sulit untuk membedakan antara aturan kontrol akses nyata dan invarian domain yang membatasi kontrol akses.
Khususnya, aturan yang bergantung pada data yang hanya tersedia jauh dalam perjalanan sepotong logika domain tertentu mungkin tidak mudah diekstraksi dari domain. Biasanya, Access Control dipanggil sebelum atau setelah operasi domain dilakukan tetapi tidak selama.
assert (forum.IsModeratedBy(moderator))
Contoh Vaughn Vernon mungkin seharusnya di luar Domain, tetapi itu tidak selalu layak.Jika ada BC Keamanan dan Anda ingin menangani logika itu, tidak perlu tahu apa itu Forum secara detail, tetapi:
sumber
moderator = securityService.GetModerator(userId, forumId)
4. Logika domain akan diimplementasikan pada objek-objek ini seperti pada moderator.EditPost () 5. Metode seperti EditPost tidak akan tahu apa-apa tentang konsep keamanan, tidak akan ada pemeriksaan tambahan di sanaOtentikasi dan Otorisasi adalah contoh buruk untuk DDD.
Tidak satu pun dari hal-hal ini yang merupakan bagian dari suatu Domain kecuali perusahaan Anda menciptakan produk keamanan.
Persyaratan Bisnis atau domain adalah, atau seharusnya, "Saya memerlukan otentikasi berbasis peran"
Anda kemudian memeriksa peran sebelum memanggil fungsi domain.
Di mana Anda memiliki persyaratan kompleks seperti 'Saya dapat mengedit posting saya sendiri tetapi tidak orang lain' memastikan bahwa domain Anda memisahkan fungsi edit
EditOwnPost()
danEditOthersPost()
sehingga Anda memiliki fungsi sederhana untuk pemetaan peranAnda juga dapat memisahkan fungsionalitas menjadi Objek Domain, seperti
Poster.EditPost()
danModerator.EditPost()
ini adalah pendekatan yang lebih OOP, meskipun pilihan Anda mungkin tergantung pada apakah metode Anda dalam Layanan Domain atau Objek Domain.Namun Anda memilih untuk memisahkan kode, pemetaan Peran akan terjadi di luar Domain. jadi misalnya jika Anda memiliki pengontrol webapi:
Seperti yang Anda lihat meskipun pemetaan peran dilakukan pada lapisan hosting, logika kompleks dari apa yang merupakan pengeditan posting Anda sendiri atau orang lain adalah bagian dari domain.
Domain mengakui perbedaan tindakan, tetapi persyaratan keamanan hanyalah bahwa "fungsi dapat dibatasi oleh peran" .
Ini mungkin lebih jelas dengan pemisahan objek domain, tetapi pada dasarnya Anda memeriksa metode yang membangun objek, bukan metode yang memanggil metode layanan. Persyaratan Anda, jika Anda masih ingin menyuarakannya sebagai bagian dari domain akan menjadi 'hanya moderator yang dapat membangun objek moderator'
sumber