Quelle est la différence entre @Secured et @PreAuthorize dans Spring Security 3?

147

Je ne sais pas quelle est la différence de sécurité du ressort entre:

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

Et

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

Je comprends que PreAuthorize peut fonctionner avec spring el mais dans mon échantillon, y a-t-il une vraie différence?

Jérôme VDL
la source

Réponses:

169

La vraie différence est que cela @PreAuthorizepeut fonctionner avec Spring Expression Language (SpEL) . Vous pouvez:

  • Accédez aux méthodes et propriétés de SecurityExpressionRoot.
  • Arguments de méthode d'accès (nécessite une compilation avec des informations de débogage ou personnalisées ParameterNameDiscoverer):

    @PreAuthorize("#contact.name == principal.name")
    public void doSomething(Contact contact)
    
  • (Fonctionnalité avancée) Ajoutez vos propres méthodes (remplacez-la MethodSecurityExpressionHandleret définissez-la comme <global-method-security><expression-handler ... /></...>).
axtavt
la source
Je ne savais pas à ce sujet, mais semble génial! : D
Alfonso Nishikawa
52

Si vous vouliez faire quelque chose comme accéder à la méthode uniquement si l'utilisateur a Role1 et Role2, vous devrez utiliser @PreAuthorize

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

En utilisant

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

Simplement, @PreAuthorizeest plus récent que @Secured.

Je dis donc qu'il est préférable de l'utiliser @PreAuthorizecar il est "basé sur une expression" et que vous pouvez utiliser des expressions comme hasRole, hasAnyRole, permitAll, etc.

Pour en savoir plus sur les expressions, consultez ces exemples d'expressions .

Dennis
la source
13

@PreAuthorizeest différent, il est plus puissant que @Secured.

  • Les @Securedannotations plus anciennes ne permettaient pas l'utilisation d'expressions.

  • À partir de Spring Security 3, les annotations @PreAuthorizeet @PostAuthorize(ainsi que @PreFilter et @PostFilter) plus flexibles sont préférables, car elles prennent en charge Spring Expression Language (SpEL) et fournissent un contrôle d'accès basé sur les expressions.

  • @Secured("ROLE_ADMIN")l'annotation est la même que @PreAuthorize ("hasRole('ROLE_ADMIN')").

  • Le @Secured({"ROLE_USER","ROLE_ADMIN")est considéré comme ROLE_USER OU ROLE_ADMIN.

vous ne pouvez donc pas exprimer la condition AND en utilisant

@ Sécurisé . Vous pouvez définir la même chose avec @PreAuthorize("hasRole('ADMIN') OR hasRole('USER')"), ce qui est plus facile à comprendre. Vous pouvez également exprimer AND, OR ou NOT (!) .

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

becher henchiri
la source
1
Lorsque vous avez annulé ma modification, dites-vous qu'il n'y a pas d'erreur à ce sujet "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
la source