Apa perbedaan antara @Secured dan @PreAuthorize di keamanan musim semi 3?

147

Tidak jelas bagi saya apa perbedaan keamanan musim semi antara:

 @PreAuthorize("hasRole('ROLE_USER')")
 public void create(Contact contact)

Dan

@Secured("ROLE_USER")
public void create(Contact contact)

Saya mengerti PreAuthorize dapat bekerja dengan spring el tetapi dalam sampel saya, apakah ada perbedaan nyata?

Jerome VDL
sumber

Jawaban:

169

Perbedaan sebenarnya adalah yang @PreAuthorizedapat bekerja dengan Spring Expression Language (SpEL) . Kamu bisa:

  • Metode dan properti akses dari SecurityExpressionRoot.
  • Argumen metode akses (memerlukan kompilasi dengan info debug atau kustom ParameterNameDiscoverer):

    @PreAuthorize("#contact.name == principal.name")
    public void doSomething(Contact contact)
    
  • (Fitur lanjutan) Tambahkan metode Anda sendiri (timpa MethodSecurityExpressionHandlerdan atur sebagai <global-method-security><expression-handler ... /></...>).
axtavt
sumber
Tidak tahu tentang ini, tetapi tampaknya luar biasa! : D
Alfonso Nishikawa
52

Jika Anda ingin melakukan sesuatu seperti mengakses metode hanya jika pengguna memiliki Role1 dan Role2 maka Anda harus menggunakan @PreAuthorize

@PreAuthorize("hasRole('ROLE_role1') and hasRole('ROLE_role2')")

Menggunakan

@Secured({"role1", "role2"}) // is treated as an OR
arnabmitra
sumber
40

Sederhananya, @PreAuthorizelebih baru dari @Secured.

Jadi saya katakan lebih baik menggunakan @PreAuthorizekarena "berbasis ekspresi" dan Anda dapat menggunakan ekspresi seperti hasRole, hasAnyRole, permitAll, dll.

Untuk mempelajari tentang ekspresi, lihat contoh ekspresi ini .

Dennis
sumber
13

@PreAuthorizeberbeda, lebih kuat dari @Secured.

  • @SecuredAnotasi yang lebih lama tidak memungkinkan ekspresi digunakan.

  • Dimulai dengan Spring Security 3, anotasi yang lebih fleksibel @PreAuthorizedan @PostAuthorize(serta @PreFilter dan @PostFilter) lebih disukai, karena mereka mendukung Spring Expression Language (SpEL) dan menyediakan kontrol akses berbasis ekspresi.

  • @Secured("ROLE_ADMIN")penjelasan sama dengan @PreAuthorize ("hasRole('ROLE_ADMIN')").

  • Ini @Secured({"ROLE_USER","ROLE_ADMIN")dianggap sebagai ROLE_USER OR ROLE_ADMIN.

jadi Anda tidak dapat mengekspresikan kondisi DAN menggunakan

@ Aman . Anda dapat mendefinisikan hal yang sama dengan @PreAuthorize("hasRole('ADMIN') OR hasRole('USER')")yang lebih mudah dipahami. Anda bisa mengekspresikan AND, ATAU, atau TIDAK (!) Juga.

@PreAuthorize ("! IsAnonymous () AND hasRole ('ADMIN')")

menjadi henchiri
sumber
1
Ketika Anda mengembalikan hasil edit saya, apakah Anda mengatakan bahwa tidak ada kesalahan dalam hal ini "hasRole('ADMIN OR hasRole('USER')"?
rigon
8
+-----------------------------------------------+----------------------------------------------------------+-----------------------------------------------------------------+
|                                               |                         @Secured                         |                         @PreAuthorize                           |
+-----------------------------------------------+----------------------------------------------------------+-----------------------------------------------------------------+
| Spring EL expressions                         | Does'nt supports.                                        | Supports                                                        |
+-----------------------------------------------+----------------------------------------------------------+-----------------------------------------------------------------+
| Multiple roles conjunctions with AND operator | Does'nt supports.(If there are multiple roles defined    | Supports                                                        |
|                                               |they will be automatically combined with OR operator)     |                                                                 |
+-----------------------------------------------+----------------------------------------------------------+-----------------------------------------------------------------+
| To enable annotation                          | Add following line to spring-security.xml                | Add following line to spring-security.xml                       |
|                                               | <global-method-security secured-annotations="enabled" /> | <global-method-security pre-post-annotations="enabled"/>        |
+-----------------------------------------------+----------------------------------------------------------+-----------------------------------------------------------------+
| Example                                       | @Secured({ROLE_ADMIN , ROLE_USER})                       | @PreAuthorize("hasRole('ROLE_USER') and hasRole('ROLE_ADMIN')") |
|                                               | public void addUser(UserInfo user){...}                  | public void addUser(UserInfo user){...}                         |
+-----------------------------------------------+----------------------------------------------------------+-----------------------------------------------------------------+
Joby Wilson Mathews
sumber