Pikirkan GrantedAuthority sebagai "izin" atau "benar". "Izin" itu (biasanya) dinyatakan sebagai string (dengan getAuthority()
metode). String itu memungkinkan Anda mengidentifikasi izin dan membiarkan pemilih Anda memutuskan apakah mereka memberikan akses ke sesuatu.
Anda dapat memberikan GrantedAuthoritys (izin) yang berbeda kepada pengguna dengan menempatkan mereka dalam konteks keamanan. Anda biasanya melakukannya dengan mengimplementasikan UserDetailsService Anda sendiri yang mengembalikan implementasi UserDetails yang mengembalikan GrantedAuthorities yang diperlukan.
Peran (seperti yang digunakan dalam banyak contoh) hanyalah "izin" dengan konvensi penamaan yang mengatakan bahwa peran adalah GrantedAuthority yang dimulai dengan awalan ROLE_
. Tidak ada lagi. Peran hanyalah GrantedAuthority - "izin" - "hak". Anda melihat banyak tempat di keamanan pegas di mana peran dengan ROLE_
awalannya ditangani secara khusus seperti misalnya di RoleVoter, di mana ROLE_
awalan digunakan sebagai default. Ini memungkinkan Anda untuk memberikan nama peran tanpa ROLE_
awalan. Sebelum keamanan Musim Semi 4, penanganan khusus "peran" ini tidak diikuti dengan sangat konsisten dan otoritas dan peran sering diperlakukan sama (seperti misalnya Anda misalnyahasAuthority()
hasRole()
). Dengan Spring Security 4, perlakuan peran lebih konsisten dan kode yang berhubungan dengan "peran" (seperti RoleVoter
, hasRole
ekspresi dll) selalu menambahkan ROLE_
awalan untuk Anda. Jadi hasAuthority('ROLE_ADMIN')
artinya sama hasRole('ADMIN')
dengan ROLE_
awalan yang ditambahkan secara otomatis. Lihat panduan migrasi 3 hingga 4 keamanan pegas untuk informasi lebih lanjut.
Tapi tetap saja: peran hanyalah otoritas dengan ROLE_
awalan khusus . Jadi di Spring keamanan 3 @PreAuthorize("hasRole('ROLE_XYZ')")
sama dengan @PreAuthorize("hasAuthority('ROLE_XYZ')")
dan di Spring keamanan 4 @PreAuthorize("hasRole('XYZ')")
sama dengan @PreAuthorize("hasAuthority('ROLE_XYZ')")
.
Mengenai kasus penggunaan Anda:
Pengguna memiliki peran dan peran dapat melakukan operasi tertentu.
Anda bisa berakhir GrantedAuthorities
untuk peran yang dimiliki pengguna dan operasi yang dapat dilakukan peran. Untuk GrantedAuthorities
peran memiliki awalan ROLE_
dan operasi memiliki awalan OP_
. Contoh bagi otoritas operasi bisa OP_DELETE_ACCOUNT
, OP_CREATE_USER
, OP_RUN_BATCH_JOB
dll Peran bisa ROLE_ADMIN
, ROLE_USER
, ROLE_OWNER
dll
Anda dapat menerapkan entitas Anda GrantedAuthority
seperti dalam contoh (pseudo-code) ini:
@Entity
class Role implements GrantedAuthority {
@Id
private String id;
@ManyToMany
private final List<Operation> allowedOperations = new ArrayList<>();
@Override
public String getAuthority() {
return id;
}
public Collection<GrantedAuthority> getAllowedOperations() {
return allowedOperations;
}
}
@Entity
class User {
@Id
private String id;
@ManyToMany
private final List<Role> roles = new ArrayList<>();
public Collection<Role> getRoles() {
return roles;
}
}
@Entity
class Operation implements GrantedAuthority {
@Id
private String id;
@Override
public String getAuthority() {
return id;
}
}
Id peran dan operasi yang Anda buat di database Anda akan menjadi representasi GrantedAuthority, misalnya ROLE_ADMIN
, OP_DELETE_ACCOUNT
dll. Ketika pengguna diautentikasi, pastikan bahwa semua GrantedAuthorities dari semua perannya dan operasi yang sesuai dikembalikan dari UserDetails.getAuthorities () metode.
Contoh: Peran admin dengan id ROLE_ADMIN
memiliki operasi OP_DELETE_ACCOUNT
, OP_READ_ACCOUNT
, OP_RUN_BATCH_JOB
ditugaskan untuk itu. Peran pengguna dengan id ROLE_USER
memiliki operasi OP_READ_ACCOUNT
.
Jika log admin dalam konteks keamanan yang dihasilkan akan memiliki GrantedAuthorities:
ROLE_ADMIN
, OP_DELETE_ACCOUNT
, OP_READ_ACCOUNT
,OP_RUN_BATCH_JOB
Jika pengguna log, itu akan memiliki:
ROLE_USER
,OP_READ_ACCOUNT
UserDetailsService akan berhati-hati untuk mengumpulkan semua peran dan semua operasi peran tersebut dan membuatnya tersedia dengan metode getAuthorities () dalam instance UserDetails yang dikembalikan.
hasRole('xyz')
di Spring Security 4 mengharapkan Anda memiliki awalan ROLE_ sedangkanhasAuthority('xyz')
tidak mengharapkan awalan dan mengevaluasi dengan tepat apa yang diteruskan. Saya menggunakan solusi ini, tetapi mengalami masalah denganhasRole('OP_MY_PERMISSION')
sejak yang ROLE_ awalan diperlukan. Sebagai gantinya, saya seharusnya menggunakanhasAuthority('OP_MY_PERMISSION')
karena saya tidak memiliki awalan.<sec:authorize access="hasRole('ADMIN')">
sama dengan<sec:authorize access="hasRole('ROLE_ADMIN')">
AFAIK Granted. Kewenangan dan peran sama dalam keamanan musim semi. String getAuthority () GrantedAuthority adalah peran (sesuai implementasi default SimpleGrantedAuthority).
Untuk kasus Anda mungkin Anda dapat menggunakan Peran Hierarkis
Bukan sol yang tepat yang Anda cari, tetapi harap ini membantu
Sunting : Membalas komentar Anda
Peran seperti izin dalam keamanan musim semi. menggunakan intercept-url dengan hasRole memberikan kontrol yang sangat halus tentang operasi apa yang diizinkan untuk peran / izin tersebut.
Cara kita menangani aplikasi kita adalah, kita mendefinisikan izin (yaitu peran) untuk setiap operasi (atau url sisanya) untuk misalnya view_account, delete_account, dll. Kemudian kita membuat profil logis untuk setiap pengguna seperti admin, guest_user, normal_user. Profil ini hanya pengelompokan logis dari izin, tidak tergantung pada keamanan pegas. Ketika pengguna baru ditambahkan, profil ditugaskan untuk itu (memiliki semua izin yang diizinkan). Sekarang ketika pengguna mencoba melakukan beberapa tindakan, izin / peran untuk tindakan tersebut diperiksa terhadap otoritas yang diberikan pengguna.
Juga defaultn RoleVoter menggunakan awalan ROLE_, sehingga otoritas yang memulai dengan ROLE_ dianggap sebagai peran, Anda dapat mengubah perilaku default ini dengan menggunakan kustom RolePrefix di role voter dan menggunakannya dalam keamanan musim semi.
sumber
Cara lain untuk memahami hubungan antara konsep-konsep ini adalah menafsirkan PERAN sebagai wadah Otoritas.
Otoritas adalah perizinan halus yang menargetkan tindakan tertentu yang terkadang digabungkan dengan lingkup atau konteks data tertentu. Misalnya, Baca, Tulis, Kelola, dapat mewakili berbagai tingkat izin untuk cakupan informasi tertentu.
Selain itu, pihak berwenang diberlakukan jauh di dalam alur pemrosesan permintaan sementara ROLE difilter dengan cara filter permintaan sebelum mencapai Controller. Praktik terbaik menentukan penerapan penegakan otoritas melewati Pengendali di lapisan bisnis.
Di sisi lain, ROLES adalah representasi berbutir kasar dari seperangkat izin. ROLE_READER hanya akan memiliki otoritas Baca atau Lihat sementara ROLE_EDITOR akan memiliki keduanya Baca dan Tulis. Peran terutama digunakan untuk penyaringan pertama di pinggiran pemrosesan permintaan seperti http. ... .antMatcher (...). hasRole (ROLE_MANAGER)
Otoritas yang ditegakkan jauh di dalam alur proses permintaan memungkinkan permohonan izin yang lebih baik. Misalnya, pengguna mungkin memiliki izin Baca Tulis untuk tingkat pertama sumber daya tetapi hanya Baca untuk sub-sumber daya. Memiliki ROLE_READER akan menahan haknya untuk mengedit sumber daya tingkat pertama karena ia memerlukan izin Tulis untuk mengedit sumber ini tetapi pencegat @PreAuthorize dapat memblokir tentatifnya untuk mengedit sub-sumber daya.
Jake
sumber
Seperti yang telah disebutkan orang lain, saya menganggap peran sebagai wadah untuk izin yang lebih rinci.
Meskipun saya menemukan implementasi Peran Hierarki kurang memiliki kontrol yang baik atas izin granular ini.
Jadi saya membuat perpustakaan untuk mengelola hubungan dan menyuntikkan izin sebagai otoritas yang diberikan dalam konteks keamanan.
Saya mungkin memiliki satu set izin di aplikasi, sesuatu seperti BUAT, BACA, PEMBARUAN, HAPUS, yang kemudian dikaitkan dengan Peran pengguna.
Atau izin yang lebih spesifik seperti READ_POST, READ_PUBLISHED_POST, CREATE_POST, PUBLISH_POST
Izin ini relatif statis, tetapi hubungan peran dengan mereka mungkin dinamis.
Contoh -
Anda dapat membuat API untuk mengelola hubungan izin ini dengan suatu peran.
Saya tidak ingin menyalin / menempelkan jawaban lain, jadi inilah tautan ke penjelasan yang lebih lengkap tentang SO.
https://stackoverflow.com/a/60251931/1308685
Untuk menggunakan kembali implementasi saya, saya membuat repo. Silakan berkontribusi!
https://github.com/savantly-net/spring-role-permissions
sumber