Saya melihat desain antarmuka saya dan saya berjuang untuk memutuskan mana yang paling "benar" cara untuk menerapkan kontrol akses berbasis peran, mengingat user
dan subject
yang user
ingin diakses.
Sejauh yang saya bisa lihat, saya memiliki tiga opsi inti (dengan yang keempat menjadi bastardisasi dari tiga yang pertama dan yang kelima menjadi tweak dari yang keempat):
- Minta
subject
dengan daftar izin yanguser
dimiliki -subject.allowAccess(user.getPermissionSet)
- Permintaan
user
dengan daftar izin yangsubject
dibutuhkan -user.hasPermissionTo(subject.getRequiredPermissions())
- Minta pihak ketiga untuk menemukan persimpangan izin -
accessController.doPermissionSetsIntersect(subject.permissionSet, user.getPermissionSet())
- Minta salah satu dari
subject
/user
, sambil mendelegasikan "keputusan" ke kelas pihak ketiga - Usahakan
user
untuk mengaksessubject
dan melemparkan kesalahan jika akses tidak diizinkan
Saya condong ke arah pilihan empat - Memiliki subject
mengandung accessController
lapangan, di mana panggilan untuk subject.userMayAccess(User user)
mendelegasikan operasi a la:
class Subject {
public function display(user) {
if(!accessController.doPermissionSetsIntersect(this.permissionSet, user.getPermissionSet())) {
display403(); //Or other.. eg, throw an error..
}
}
}
.. tapi kemudian ini menimbulkan pertanyaan lebih lanjut:
- haruskah
accessController
bidang vs kelas statis ..? - Haruskah
subject
mengetahui izin apa yang diperlukan untuk dapat melihatnya? - di mana asas paling sedikit ilmu berperan di sini, sehubungan dengan pemanggilan
subject.display()
? Haruskah peneleponsubject.display()
mengetahui bahwa kontrol akses berlaku? (di manasubject.display()
"metode templat" terakhir) - telah
subject.display()
mengelola kontrol akses, melemparkan pengecualian di mana pengguna tidak memiliki izin yang diperlukan?
Apa yang akan dianggap "praktik terbaik" dalam situasi ini? Di mana seharusnya tanggung jawab untuk melakukan pemeriksaan sebenarnya terjadi?
Karena ini merupakan latihan akademis yang kemudian akan berkembang menjadi implementasi, referensi untuk pola desain akan dihargai.
Saya pikir pilihan Anda 3 adalah yang paling dekat, tetapi alih-alih menginterogasi
user
dansubject
tentang set izin mereka, Anda harus meneruskanuser
dansubject
ke pengontrol akses.Pengontrol akses harus bertanggung jawab untuk mendapatkan set izin dan memeriksa apakah aksesnya memadai. Dengan begitu Anda mengisolasi logika penyimpanan dan logika pemeriksaan di pengontrol akses Anda, terpisah dari pengguna dan subjek.
Elemen lain yang mungkin hilang dari contoh Anda adalah operasi apa yang sedang dilakukan. Beberapa pengguna mungkin memiliki hak untuk membaca beberapa data tetapi tidak untuk memperbarui, menghapus, mengeksekusi, dll Jadi Anda mungkin memiliki
checkAccess
metode pada kontroler akses dengan tiga parameter:user
,subject
,operation
. Anda mungkin juga ingin memberikan beberapa informasi tambahancheckAccess
untuk mengembalikan informasi tentang mengapa akses tidak diberikan.Misalnya, mendelegasikan semua ini ke pengontrol akses nanti memungkinkan Anda untuk mengganti cara izin Anda diwakili. Anda mungkin mulai dengan kontrol akses berbasis peran dan pindah ke berbasis klaim nanti. Anda dapat menyimpan izin dalam struktur sederhana untuk memulai dan kemudian menambahkan grup hierarki / peran dan operasi yang diizinkan pada berbagai jenis subjek. Tidak menempatkan set izin Anda ke antarmuka membantu mengaktifkannya.
Apakah Anda menggunakan AOP atau kode boilerplate untuk menyambungkan ini, menurut pendapat saya, kurang penting.
sumber