Peran vs Kontrol Akses Berbasis Izin

45

Saya mencoba memahami tradeoff yang melekat antara peran dan izin ketika datang ke kontrol akses (otorisasi).

Mari kita mulai dengan yang diberikan: dalam sistem kami, Izin akan menjadi unit akses berbutir halus (" Edit sumber daya X ", " Akses halaman dasbor ", dll.). Sebuah Peran akan menjadi koleksi 1+ Permissions. Seorang Pengguna dapat memiliki 1+ Peran. Semua hubungan ini (Pengguna, Peran, Izin) semuanya disimpan dalam database dan dapat diubah dengan cepat dan sesuai kebutuhan.

Kekhawatiran saya:

(1) Apa yang "buruk" tentang memeriksa Peran untuk kontrol akses? Apa manfaat yang diperoleh dengan memeriksa izin? Dengan kata lain, apa perbedaan antara kedua cuplikan di bawah ini:

if(SecurityUtils.hasRole(user)) {
    // Grant them access to a feature
}

// vs.
if(SecurityUtils.hasPermission(user)) {
    // Grant them access to a feature
}

Dan:

(2) Dalam skenario ini, nilai berguna apa yang diberikan peran bahkan? Tidak bisakah kita hanya menetapkan 1+ Izin untuk Pengguna secara langsung? Apa yang konkrit nilai abstraksi jangan Peran menawarkan (contoh bisa seseorang memberi tertentu)?

smeeb
sumber
2
Beberapa poin: (1) pengguna tunggal mungkin memiliki beberapa peran, (2) Anda mungkin ingin melihat ACL (Access Control Lists), misalnya. Anda mungkin ingin dapat memberikan "Akses halaman dasbor" hanya sebagian dari halaman dasbor (jika ada beberapa).
Matthieu M.

Jawaban:

63

(1) Apa yang "buruk" tentang memeriksa Peran untuk kontrol akses? Apa manfaat yang diperoleh dengan memeriksa izin?

Pada saat memeriksa, kode panggilan hanya perlu tahu "apakah pengguna X memiliki izin untuk melakukan tindakan Y?" .
Kode panggilan tidak mempedulikan dan seharusnya tidak menyadari hubungan antara peran dan izin.

Lapisan otorisasi kemudian akan memeriksa apakah pengguna memiliki izin ini, biasanya dengan memeriksa apakah peran pengguna memiliki izin ini. Ini memungkinkan Anda untuk mengubah logika otorisasi tanpa memperbarui kode panggilan.

Jika Anda secara langsung memeriksa peran di situs panggilan, Anda secara implisit membentuk peran ⇄ hubungan izin dan menyuntikkan logika otorisasi ke dalam kode panggilan, melanggar pemisahan kekhawatiran.

Jika nanti Anda memutuskan bahwa peran footidak boleh memiliki izin baz, Anda harus mengubah setiap kode yang memeriksa apakah pengguna adalah a foo.

(2) Dalam skenario ini, nilai berguna apa yang diberikan peran bahkan? Tidak bisakah kita hanya menetapkan 1+ Izin untuk Pengguna secara langsung? Nilai abstraksi konkret apa yang ditawarkan Peran (dapatkah seseorang memberikan contoh spesifik)?

Peran secara konseptual mewakili kumpulan izin yang bernama.

Katakanlah Anda menambahkan fitur baru yang memungkinkan pengguna mengedit pengaturan tertentu. Fitur ini harus tersedia hanya untuk administrator.

Jika Anda menyimpan izin per pengguna, Anda harus menemukan semua pengguna di database Anda yang entah bagaimana Anda ketahui adalah administrator (Jika Anda tidak menyimpan informasi peran untuk pengguna, bagaimana Anda bahkan tahu pengguna mana yang merupakan administrator?) , Dan menambahkan izin ini ke daftar izin mereka.

Jika Anda menggunakan peran, Anda hanya perlu menambahkan izin untuk Administratorperan tersebut, yang keduanya lebih mudah dilakukan, lebih banyak ruang yang efisien, dan kurang rentan terhadap kesalahan.

Rotem
sumber
Uh? The lapisan otentikasi akan memeriksa bahwa pengguna adalah dia yang mengaku; lapisan yang memeriksa fungsi / data mana yang dapat diakses oleh pengguna tersebut adalah lapisan otorisasi
SJuan76
4
Ini harus menjadi bacaan wajib untuk semua programmer. Luar biasa.
Kosta Kontos
2
Sederhana, ringkas, dan to the point - mengalahkan seluruh bab buku di suatu tempat. Terima kasih.
Dan Nissenbaum
2
Komentar untuk kejelasan (dan tolong perbaiki saya jika saya salah): Sebuah authorization layerkemungkinan berarti tidak lebih dari sekadar memiliki definisi fungsi (yaitu) secara user->hasPermission(SOME_PERMISSION)internal memeriksa peran pengguna terlebih dahulu dan kemudian memeriksa apakah ada peran yang memasukkan / mengecualikan yang diberikan izin. Sebagai contoh, the calling codemungkin memeriksa untuk melihat apakah halaman tertentu terlihat bagi pengguna dan akan memanggil user->hasPermission(VIEW_GIVEN_PAGE), dan authorization layerterdiri dari definisi dari hasPermissionfungsi yang memeriksa peran seperti di atas.
Dan Nissenbaum
1
@DanNissenbaum Ya, sepertinya Anda melakukannya dengan benar, bisa sesederhana hanya memeriksa apakah peran pengguna memiliki otorisasi ini. Bisa juga lebih dari itu. Misalnya, mungkin Anda memiliki opsi untuk menangguhkan sementara pengguna dan dalam hal ini hasPermissiondapat memeriksa usersRole.HasPermission(VIEW_GIVEN_PAGE) && !user.Suspended. Intinya adalah semua itu dilakukan di satu tempat dan tidak dalam mengkonsumsi kode (panggilan).
Rotem
18

Menanggapi pertanyaan pertama Anda, masalah terbesar dengan memeriksa bahwa pengguna memiliki peran daripada izin tertentu, adalah bahwa izin dapat dipegang oleh beberapa peran. Sebagai contohnya, pengembang mungkin memiliki akses untuk melihat portal pengembang di intranet perusahaan, yang mungkin juga merupakan izin yang dimiliki oleh manajer mereka. Jika pengguna kemudian mencoba mengakses portal pengembang, Anda akan memiliki cek yang mirip dengan:

if(SecurityUtils.hasRole(developer)) {
    // Grant them access to a feature
} else if(SecurityUtils.hasRole(manager)) {
    // Grant them access to a feature
} else if...

( switchPernyataan dalam bahasa pilihan Anda akan lebih baik, tetapi masih tidak terlalu rapi)

Semakin umum atau banyak dipegang izin, semakin banyak peran pengguna yang perlu Anda periksa untuk memastikan bahwa seseorang dapat mengakses sistem yang diberikan. Ini juga akan mengarah pada masalah bahwa setiap kali Anda memodifikasi izin untuk peran, Anda perlu memodifikasi cek untuk mencerminkan hal ini. Dalam sistem besar ini akan menjadi sangat berat dengan sangat cepat.

Jika Anda hanya memeriksa bahwa pengguna memiliki izin yang memungkinkan mereka mengakses portal pengembang misalnya, tidak masalah peran apa yang mereka miliki, mereka akan diberikan akses.

Untuk menjawab pertanyaan kedua Anda, alasan Anda memiliki peran adalah karena mereka bertindak semudah memodifikasi dan mendistribusikan "paket" izin. Jika Anda memiliki sistem yang memiliki ratusan peran dan ribuan izin, menambahkan pengguna baru (misalnya manajer SDM baru) akan mengharuskan Anda untuk melaluinya dan memberi mereka setiap izin tunggal yang dimiliki oleh manajer SDM lainnya. Tidak hanya akan membosankan, tetapi juga rentan terhadap kesalahan jika dilakukan secara manual. Bandingkan ini dengan hanya menambahkan peran "manajer SDM" ke profil pengguna, yang akan memberi mereka akses yang sama seperti setiap pengguna lain dengan peran itu.

Anda dapat berargumen bahwa Anda dapat dengan mudah mengkloning pengguna yang ada (jika sistem Anda mendukung ini), tetapi sementara ini memang memberi pengguna izin yang benar untuk saat itu, mencoba untuk menambah atau menghapus izin untuk semua pengguna di masa depan mungkin sulit. Contoh skenario untuk ini adalah jika mungkin di masa lalu staf SDM juga bertanggung jawab atas penggajian, tetapi kemudian perusahaan menjadi cukup besar untuk mempekerjakan staf khusus untuk menangani penggajian. Ini berarti bahwa SDM tidak perlu lagi mengakses sistem penggajian, sehingga izin dapat dihapus. Jika Anda memiliki 10 anggota HR yang berbeda, Anda harus melalui secara manual dan memastikan Anda menghapus izin yang benar yang memperkenalkan kemungkinan kesalahan pengguna. Masalah lain dengan ini adalah bahwa itu tidak berskala; saat Anda mendapatkan lebih banyak dan lebih banyak pengguna dalam peran tertentu, itu membuat modifikasi peran jauh lebih sulit. Bandingkan ini dengan menggunakan peran, di mana Anda hanya perlu mengubah peran menyeluruh yang dimaksud untuk menghapus izin, yang akan tercermin oleh setiap pengguna yang memegang peran itu.

Matt Champion
sumber
contoh yang bagus, terima kasih!
jujur