1. Обзор
В этой статье мы узнаем, как использовать @PreFilter и @PostFilter аннотации для обеспечения безопасности операций в приложении Spring.
При использовании вместе с достоверной основной информацией @PreFilter и @PostFilter позволяет нам определить мелкозернистые правила безопасности с помощью языка весеннего выражения.
2. Введение @PreFilter и @PostFilter
Проще говоря, @PreFilter и @PostFilter аннотации используется для фильтрации списков объектов на основе пользовательских правил безопасности, которые мы определяем.
@PostFilter определяет правило для фильтрации списка возврата метода, по применяя это правило к каждому элементу списка . Если оцениваемое значение соответствует действительности, товар будет храниться в списке. В противном случае элемент будет удален.
@PreFilter работает очень похоже, однако, фильтрация применяется к списку, который передается в качестве входного параметра к аннотированному методу.
Обе аннотации могут быть использованы на методы или типы (классы и интерфейсы). Мы будем использовать их только на методах на протяжении всей этой статьи.
Такие аннотации не активны по умолчанию – мы должны включить их с помощью @EnableGlobalMethodSecurity аннотация и нелепое – в нашей конфигурации безопасности:
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { // ... }
3. Написание правил безопасности
Чтобы написать правила безопасности в этих двух аннотациях – мы будем использовать выражения Весна-EL; мы также можем использовать встроенный объект фильтрОбъект для того чтобы получить справку к определенному элементу списка будучи испытано.
Весенняя безопасность обеспечивает многие другие встроенные объекты для создания очень конкретных и точных правил.
Например, , мы можем использовать @PreFilter чтобы проверить, если назначенный имущество Задача объект равен имя пользователя, который в настоящее время проходит проверку подлинности:
@PostFilter("filterObject.assignee == authentication.name") ListfindAll() { ... }
Мы использовали @PostFilter аннотация здесь, так как мы хотим, чтобы метод для выполнения и получить все задачи в первую очередь, и они проходят каждую задачу из списка через наше правило фильтра.
Таким образом, если аутентифицированный пользователь Майкл , окончательный список задач, возвращенных найтиВсе метод будет содержать только задачи, назначенные Майкл , даже если база данных имеет задачи, возложенные на Джим и Пэм .
Теперь давайте немного интереснее. Предположим, что если пользователь является менеджером, он может видеть все задачи, независимо от того, кому он назначен:
@PostFilter("hasRole('MANAGER') or filterObject.assignee == authentication.name") ListfindAll() { // ... }
Мы использовали встроенный метод имеетРоле чтобы проверить, имеет ли аутентифицированный пользователь роль MANAGER. Если имеетРоле возвращается верно, задача будет храниться в окончательном списке. Таким образом, если пользователь является менеджером, правило будет возвращаться верно для каждого элемента в списке. Таким образом, окончательный список будет содержать все элементы.
Теперь давайте отфильтруем список, переданный в качестве параметра сохранить метод с использованием @PreFilter :
@PreFilter("hasRole('MANAGER') or filterObject.assignee == authentication.name") Iterablesave(Iterable entities) { // ... }
Правило безопасности такое же, как то, что мы использовали на @PostFilter пример. Основное отличие здесь заключается в том, что элементы списка будут отфильтрованы до выполнения метода, что позволит нам удалить некоторые элементы из списка, предотвращая их сохранены в базе данных.
Так Джим , который не является менеджером, может попытаться сохранить список задач, некоторые из которых назначены Пэм . Однако только те задачи, которые возложены Джим будут включены, остальные будут проигнорированы.
4. Производительность в больших списках
@PreFilter действительно здорово и просто в использовании, но это может быть неэффективным при работе с очень большими списками, так как операция извлечения будет получить все данные и применить фильтр потом.
Представьте себе, например, что у нас есть тысячи задач в нашей базе данных, и мы хотим, чтобы получить пять задач, которые в настоящее время назначены Пэм . Если мы используем @PreFilter , операция базы данных будет приносить все задачи в первую очередь, и итерировать через все из них, чтобы отфильтровать те, которые не назначены Пэм .
5. Заключение
В этой быстрой статье объясняется, как создать простое, но безопасное приложение с помощью приложения Spring Security @PreFilter и @PostFilter Аннотации.
Проверьте полный пример кода в этом репозитории Github .