Saya mencoba membuat kerangka kerja ACL yang fleksibel di Java untuk aplikasi saya.
Banyak kerangka kerja ACL dibangun di atas daftar putih aturan, di mana aturan ada dalam bentuk pemilik: action: resource . Sebagai contoh,
- "JOHN bisa MELIHAT sumber daya FOOBAR-1"
- "MARY can VIEW resource FOOBAR-1"
- "MARY can EDIT resource FOOBAR-1"
Ini menarik karena aturan dapat dengan mudah diserialisasi / dipertahankan ke database. Tetapi aplikasi saya memiliki logika bisnis yang kompleks. Sebagai contoh,
- "Semua pengguna di departemen 1 dengan senioritas lebih dari 5 tahun dapat MELIHAT sumber daya FOOBAR-1, jika tidak, tidak boleh"
- "Semua pengguna di departemen 2, jika tanggalnya setelah 15/3/2016, dapat MELIHAT sumber daya FOOBAR-2, kalau tidak, tidak akan diizinkan"
Setelah dipikirkan pertama kali, akan menjadi mimpi buruk untuk menyusun skema basis data yang dapat menangani aturan yang sangat rumit seperti ini. Oleh karena itu, sepertinya saya perlu "memanggang" mereka ke dalam aplikasi yang dikompilasi, mengevaluasi mereka untuk setiap pengguna, dan kemudian menghasilkan pemilik: tindakan: aturan sumber daya sebagai hasil dari evaluasi. Saya ingin menghindari memanggang logika ke dalam aplikasi yang dikompilasi.
Jadi, saya berpikir untuk mewakili aturan dalam bentuk predikat : action: resource , di mana predikatnya adalah ekspresi boolean yang menentukan apakah pengguna diizinkan. Predikatnya akan berupa string ekspresi JavaScript yang dapat dievaluasi oleh mesin Rhino Java. Sebagai contoh,
return user.getDept() == 1 && user.seniority > 5;
Dengan melakukan itu, predikat dapat dengan mudah disimpan ke dalam basis data.
Apakah ini pintar ? Apakah ini ceroboh ? Apakah ini menarik perhatian ? Apakah ini rekayasa berlebihan ? Apakah ini aman (rupanya, Jawa bisa mem-sandbox mesin Rhino).
sumber
Jawaban:
Memipis data dinamis ke juru bahasa implementasi Anda biasanya merupakan ide yang buruk, karena hal itu meningkatkan potensi korupsi data menjadi potensi pengambilalihan aplikasi jahat. Dengan kata lain, Anda akan keluar dari cara Anda untuk membuat sebuah kode injeksi kerentanan.
Masalah Anda dapat diselesaikan dengan lebih baik oleh mesin aturan atau mungkin bahasa khusus domain (DSL) . Lihatlah konsep-konsep itu, tidak perlu menemukan kembali roda.
sumber
==
bukan===
dalam contoh Anda. Apakah Anda benar-benar ingin memberikan kelengkapan turing ketika semua aturan harus selalu berakhir? Alih-alih melompat-lompat untuk memastikan semua interaksi antara Jawa dan JavaScript adalah halal, mengapa Anda tidak menulis parser dan juru bahasa sederhana seperti yang disarankan Kilian? Akan jauh lebih mudah untuk menyesuaikan dengan kebutuhan dan keamanan Anda. Gunakan ANTLR atau sesuatu.while (true) ;
Saya melakukan ini, dan saya sarankan Anda tidak melakukannya.
Apa yang saya lakukan adalah menulis semua logika bisnis dalam Lua, dan menyimpan skrip Lua itu dalam database. Ketika aplikasi saya mulai itu akan memuat dan menjalankan skrip. Dengan begitu saya dapat memperbarui logika bisnis aplikasi saya tanpa mendistribusikan biner baru.
Saya selalu menemukan bahwa saya selalu perlu memperbarui biner ketika membuat perubahan. Beberapa perubahan ada di skrip Lua, tapi saya selalu punya daftar perubahan yang perlu dibuat, dan akhirnya saya hampir selalu harus membuat beberapa perubahan dalam biner dan beberapa perubahan dalam skrip Lua. Imajinasi saya bahwa saya bisa menghindari mendistribusikan binari sepanjang waktu tidak berhasil.
Apa yang saya temukan jauh lebih bermanfaat adalah memudahkan distribusi binari. Aplikasi saya secara otomatis memeriksa pembaruan pada startup, mengunduh, dan menginstal pembaruan apa pun. Pengguna saya selalu berada di binari terbaru yang saya dorong. Hampir tidak ada perbedaan antara perubahan dalam biner dan perubahan dalam skrip. Jika saya melakukannya lagi, saya akan berusaha lebih keras untuk membuat pembaruan tanpa cacat.
sumber
Database saya tidak akan berisi kode. Tetapi Anda dapat melakukan sesuatu yang serupa dengan memiliki database yang berisi nama fungsi dan kemudian menggunakan refleksi untuk memanggil mereka. Ketika Anda menambahkan kondisi baru, Anda harus menambahkannya ke kode dan basis data Anda, tetapi Anda dapat menggabungkan kondisi dan parameter yang diteruskan ke mereka untuk membuat evaluasi yang cukup kompleks.
Dengan kata lain, jika Anda memiliki departemen bernomor, akan mudah untuk memiliki cek UserDepartmentIs dan cek TodayIsAfter dan kemudian menggabungkannya untuk memiliki Department = 2 dan Today> 15/03/2016. Jika Anda ingin memiliki cek TodayIsBefore sehingga Anda dapat mengakhiri tanggal izin, Anda harus menulis fungsi TodayIsBefore.
Saya belum melakukan ini untuk izin pengguna, tetapi telah melakukannya untuk validasi data, tetapi harus berfungsi.
sumber
XACML adalah solusi yang benar-benar Anda cari. Ini adalah jenis mesin aturan yang berfokus pada kontrol akses saja. XACML, standar yang ditentukan oleh OASIS, mendefinisikan tiga bagian:
Arsitekturnya adalah sebagai berikut:
Seperti apa kasus penggunaan pertama Anda:
Kasus penggunaan kedua Anda adalah:
Anda dapat menggabungkan kedua kasus penggunaan menjadi satu kebijakan dengan menggunakan referensi:
Dan kamu selesai!
Anda dapat membaca lebih lanjut tentang XACML dan ALFA dari:
sumber
Yang Anda inginkan di sini adalah XACML . Cukup banyak memberi Anda apa yang Anda inginkan. Anda tidak perlu harus mengimplementasikan arsitektur lengkap dengan semua peran yang benar-benar terpisah ... jika Anda hanya memiliki satu aplikasi, Anda mungkin bisa lolos dengan mengintegrasikan PDP dan PEP ke dalam aplikasi Anda dengan balana dan PIP adalah apa pun basis data pengguna Anda saat ini.
Sekarang, di mana saja di aplikasi Anda Anda perlu mengesahkan sesuatu, Anda membuat permintaan XACML yang memiliki pengguna, tindakan, dan konteksnya, dan mesin XACML akan membuat keputusan berdasarkan pada file kebijakan XACML yang Anda tulis. File-file kebijakan ini dapat disimpan dalam database atau pada filesystem, atau di mana pun Anda ingin menyimpan konfigurasi. Axiomatics memiliki alternatif yang bagus untuk representasi XACML XML yang disebut ALFA yang sedikit lebih mudah dibaca daripada XML mentah, dan plugin Eclipse untuk menghasilkan XACML XML dari kebijakan ALFA.
sumber
Kami melakukan ini di perusahaan saya saat ini, dan kami sangat senang dengan hasilnya.
Ekspresi kami ditulis dalam js, dan kami bahkan menggunakannya untuk membatasi hasil yang dapat diperoleh pengguna dari permintaan ElasticSearch.
Triknya adalah memastikan bahwa tersedia cukup info untuk membuat keputusan, sehingga Anda dapat benar-benar menulis perm apa pun yang Anda inginkan tanpa perubahan kode, tetapi pada saat yang sama menjaga agar tetap cepat.
Kami tidak benar-benar khawatir dengan serangan injeksi kode, karena izin ditulis oleh mereka yang tidak perlu menyerang sistem. Dan hal yang sama berlaku untuk serangan DOS seperti
while(true)
contohnya. Admin sistem tidak perlu melakukan itu, mereka hanya bisa menghapus izin semua orang ...Memperbarui:
Sesuatu seperti XACML tampaknya lebih baik sebagai titik manajemen auth pusat untuk suatu organisasi. Kasus penggunaan kami sedikit berbeda karena klien kami tidak memiliki departemen TI untuk menjalankan semua itu. Kami membutuhkan sesuatu yang mandiri tetapi berusaha mempertahankan fleksibilitas sebanyak mungkin.
sumber