Qual é a diferença entre @Secured e @PreAuthorize na primavera security 3?

147

Não está claro para mim qual é a diferença na segurança da primavera entre:

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

E

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

Entendo que o PreAuthorize pode funcionar com a Spring el, mas na minha amostra, há uma diferença real?

Jerome VDL
fonte

Respostas:

169

A diferença real é que @PreAuthorizepode funcionar com o Spring Expression Language (SpEL) . Você pode:

  • Métodos de acesso e propriedades de SecurityExpressionRoot.
  • Argumentos do método de acesso (requer compilação com informações de depuração ou personalizadas ParameterNameDiscoverer):

    @PreAuthorize("#contact.name == principal.name")
    public void doSomething(Contact contact)
    
  • (Recurso avançado) Adicione seus próprios métodos (substitua MethodSecurityExpressionHandlere defina-o como <global-method-security><expression-handler ... /></...>).
axtavt
fonte
Não sabia disso, mas parece incrível! : D
Alfonso Nishikawa
52

Se você quiser fazer algo como acessar o método apenas se o usuário tiver Função1 e Função2, será necessário usar @PreAuthorize

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

Usando

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

Simplesmente, @PreAuthorizeé mais novo que @Secured.

Então, eu digo que é melhor usar @PreAuthorize, pois é "baseado em expressão" e você pode usar expressões como hasRole, hasAnyRole, allowAll etc.

Para aprender sobre expressões, consulte estes exemplos de expressões .

Dennis
fonte
13

@PreAuthorizeé diferente, é mais poderoso que @Secured.

  • As @Securedanotações mais antigas não permitiam o uso de expressões.

  • A partir do Spring Security 3, as anotações mais flexíveis @PreAuthorizee @PostAuthorize(assim como @PreFilter e @PostFilter) são preferidas, pois oferecem suporte ao Spring Expression Language (SpEL) e fornecem controle de acesso baseado em expressão.

  • @Secured("ROLE_ADMIN")anotação é igual a @PreAuthorize ("hasRole('ROLE_ADMIN')").

  • O @Secured({"ROLE_USER","ROLE_ADMIN")é considerado como ROLE_USER OU ROLE_ADMIN.

então você não pode expressar a condição AND usando

@Secured . Você pode definir o mesmo com @PreAuthorize("hasRole('ADMIN') OR hasRole('USER')"), o que é mais fácil de entender. Você pode expressar AND, OR ou NOT (!) Também.

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

becher henchiri
fonte
1
Ao reverter minha edição, você está dizendo que não há erro nisso "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
fonte