Jaka jest różnica między @Secured i @PreAuthorize w Spring Security 3?

147

Nie jest dla mnie jasne, jaka jest różnica w zabezpieczeniach wiosennych między:

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

I

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

Rozumiem, że PreAuthorize może współpracować z spring el, ale czy w mojej próbce jest prawdziwa różnica?

Jerome VDL
źródło

Odpowiedzi:

169

Prawdziwa różnica polega na tym, że @PreAuthorizemoże współpracować z językiem Spring Expression Language (SpEL) . Możesz:

  • Uzyskaj dostęp do metod i właściwości SecurityExpressionRoot.
  • Dostęp do argumentów metody (wymaga kompilacji z informacjami debugowania lub niestandardowymi ParameterNameDiscoverer):

    @PreAuthorize("#contact.name == principal.name")
    public void doSomething(Contact contact)
    
  • (Funkcja zaawansowana) Dodaj własne metody (nadpisz MethodSecurityExpressionHandleri ustaw jako <global-method-security><expression-handler ... /></...>).
axtavt
źródło
Nie wiedziałem o tym, ale wydaje się niesamowity! : D
Alfonso Nishikawa
52

Jeśli chciałbyś zrobić coś takiego jak dostęp do metody tylko wtedy, gdy użytkownik ma Role1 i Role2, musisz użyć @PreAuthorize

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

Za pomocą

@Secured({"role1", "role2"}) // is treated as an OR
arnabmitra
źródło
40

Po prostu @PreAuthorizejest nowszy niż @Secured.

Więc mówię, że lepiej jest używać, @PreAuthorizeponieważ jest "oparty na wyrażeniach" i możesz używać wyrażeń takich jak hasRole, hasAnyRole, allowAll itp.

Aby dowiedzieć się więcej o wyrażeniach, zobacz te przykładowe wyrażenia .

Dennis
źródło
13

@PreAuthorizejest inny, jest mocniejszy niż @Secured.

  • Starsze @Securedadnotacje nie pozwalały na użycie wyrażeń.

  • Począwszy od Spring Security 3, preferowane są bardziej elastyczne adnotacje @PreAuthorizei @PostAuthorize(a także @PreFilter i @PostFilter), ponieważ obsługują one język Spring Expression (SpEL) i zapewniają kontrolę dostępu opartą na wyrażeniach.

  • @Secured("ROLE_ADMIN")adnotacja jest taka sama jak @PreAuthorize ("hasRole('ROLE_ADMIN')").

  • @Secured({"ROLE_USER","ROLE_ADMIN")Jest uważany za ROLE_USER LUB ROLE_ADMIN.

więc nie możesz wyrazić warunku AND za pomocą

@Secured . Możesz zdefiniować to samo za pomocą @PreAuthorize("hasRole('ADMIN') OR hasRole('USER')"), co jest łatwiejsze do zrozumienia. Możesz również wyrazić AND, OR lub NOT (!) .

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

becher henchiri
źródło
1
Czy wycofując moją zmianę, twierdzisz, że nie ma w tym błędu "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
źródło