¿Cuál es la diferencia entre @Secured y @PreAuthorize en Spring Security 3?

147

Para mí no está claro cuál es la diferencia en la seguridad de primavera entre:

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

Y

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

Entiendo que PreAuthorize puede funcionar con spring el pero, en mi muestra, ¿hay alguna diferencia real?

Jerome VDL
fuente

Respuestas:

169

La verdadera diferencia es que @PreAuthorizepuede funcionar con Spring Expression Language (SpEL) . Usted puede:

  • Métodos de acceso y propiedades de SecurityExpressionRoot.
  • Argumentos del método de acceso (requiere compilación con información de depuración o personalizada ParameterNameDiscoverer):

    @PreAuthorize("#contact.name == principal.name")
    public void doSomething(Contact contact)
    
  • (Característica avanzada) Agregue sus propios métodos (anule MethodSecurityExpressionHandlery configúrelo como <global-method-security><expression-handler ... /></...>).
axtavt
fuente
¡No sabía sobre esto, pero parece increíble! : D
Alfonso Nishikawa
52

Si quisieras hacer algo como acceder al método solo si el usuario tiene Role1 y Role2, entonces deberías usar @PreAuthorize

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

Utilizando

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

Simplemente, @PreAuthorizees más nuevo que @Secured.

Entonces, digo que es mejor usarlo @PreAuthorizeya que está "basado en expresiones" y puede usar expresiones como hasRole, hasAnyRole, permitAll, etc.

Para aprender sobre expresiones, vea estos ejemplos de expresiones .

Dennis
fuente
13

@PreAuthorizees diferente, es más poderoso que @Secured.

  • Las @Securedanotaciones anteriores no permitían el uso de expresiones.

  • A partir de Spring Security 3, se prefieren las anotaciones más flexibles @PreAuthorizey @PostAuthorize(además de @PreFilter y @PostFilter), ya que admiten Spring Expression Language (SpEL) y proporcionan control de acceso basado en expresiones.

  • @Secured("ROLE_ADMIN")anotación es lo mismo que @PreAuthorize ("hasRole('ROLE_ADMIN')").

  • El @Secured({"ROLE_USER","ROLE_ADMIN")se considera como ROLE_USER O ROLE_ADMIN.

así que no puedes expresar la condición AND usando

@Segured . Puede definir lo mismo con @PreAuthorize("hasRole('ADMIN') OR hasRole('USER')"), que es más fácil de entender. Puede expresar AND, OR o NOT (!) .

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

becher henchiri
fuente
1
Al revertir mi edición, ¿estás diciendo que no hay ningún error en esto "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
fuente