В чем разница между @Secured и @PreAuthorize в весенней безопасности 3?

147

Для меня не ясно, в чем разница в весенней безопасности между:

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

И

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

Я понимаю, что PreAuthorize может работать с Spring El, но в моем примере есть реальная разница?

Джером VDL
источник

Ответы:

169

Реальная разница в том, что @PreAuthorizeможно работать с Spring Expression Language (SpEL) . Ты можешь:

  • Доступ к методам и свойствам SecurityExpressionRoot.
  • Доступ к аргументам метода (требуется компиляция с отладочной информацией или пользовательские ParameterNameDiscoverer):

    @PreAuthorize("#contact.name == principal.name")
    public void doSomething(Contact contact)
    
  • (Расширенная функция) Добавьте свои собственные методы (переопределите MethodSecurityExpressionHandlerи установите его как <global-method-security><expression-handler ... /></...>).
axtavt
источник
Не знал об этом, но кажется потрясающим! : D
Альфонсо Нишикава
52

Если вы хотите сделать что-то вроде доступа к методу, только если у пользователя есть Role1 и Role2, вам придется использовать @PreAuthorize.

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

С помощью

@Secured({"role1", "role2"}) // is treated as an OR
arnabmitra
источник
40

Просто @PreAuthorizeновее чем @Secured.

Поэтому я говорю, что его лучше использовать, @PreAuthorizeпоскольку он «основан на выражениях», и вы можете использовать такие выражения, как hasRole, hasAnyRole, allowAll и т. Д.

Чтобы узнать о выражениях, посмотрите эти примеры выражений .

Деннис
источник
13

@PreAuthorizeотличается, это более мощный, чем @Secured.

  • Старые @Securedаннотации не позволяли использовать выражения.

  • Начиная с Spring Security 3, предпочтение отдается более гибким аннотациям @PreAuthorizeи @PostAuthorize(а также @PreFilter и @PostFilter), поскольку они поддерживают Spring Expression Language (SpEL) и обеспечивают управление доступом на основе выражений.

  • @Secured("ROLE_ADMIN")аннотация такая же, как @PreAuthorize ("hasRole('ROLE_ADMIN')").

  • Это @Secured({"ROLE_USER","ROLE_ADMIN")считается ROLE_USER ИЛИ ROLE_ADMIN.

так что вы не можете выразить условие AND, используя

@ Защищено . Вы можете определить то же самое с @PreAuthorize("hasRole('ADMIN') OR hasRole('USER')"), что легче понять. Вы также можете выразить AND, OR или NOT (!) .

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

бехер хенчири
источник
1
Когда вы вернули мое редактирование, вы говорите, что в этом нет ошибки "hasRole('ADMIN OR hasRole('USER')"?
Ригон
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){...}                         |
+-----------------------------------------------+----------------------------------------------------------+-----------------------------------------------------------------+
Джоби Уилсон Мэтьюз
источник