Рубрики
Без рубрики

Весенняя безопасность – @PreFilter и @PostFilter

Узнайте, как использовать аннотации @PreFilter и @PostFilter весенней безопасности на практических примерах.

Автор оригинала: baeldung.

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")
List findAll() {
    ...
}

Мы использовали @PostFilter аннотация здесь, так как мы хотим, чтобы метод для выполнения и получить все задачи в первую очередь, и они проходят каждую задачу из списка через наше правило фильтра.

Таким образом, если аутентифицированный пользователь Майкл , окончательный список задач, возвращенных найтиВсе метод будет содержать только задачи, назначенные Майкл , даже если база данных имеет задачи, возложенные на Джим и Пэм .

Теперь давайте немного интереснее. Предположим, что если пользователь является менеджером, он может видеть все задачи, независимо от того, кому он назначен:

@PostFilter("hasRole('MANAGER') or filterObject.assignee == authentication.name")
List findAll() {
    // ...
}

Мы использовали встроенный метод имеетРоле чтобы проверить, имеет ли аутентифицированный пользователь роль MANAGER. Если имеетРоле возвращается верно, задача будет храниться в окончательном списке. Таким образом, если пользователь является менеджером, правило будет возвращаться верно для каждого элемента в списке. Таким образом, окончательный список будет содержать все элементы.

Теперь давайте отфильтруем список, переданный в качестве параметра сохранить метод с использованием @PreFilter :

@PreFilter("hasRole('MANAGER') or filterObject.assignee == authentication.name")
Iterable save(Iterable entities) {
    // ...
}

Правило безопасности такое же, как то, что мы использовали на @PostFilter пример. Основное отличие здесь заключается в том, что элементы списка будут отфильтрованы до выполнения метода, что позволит нам удалить некоторые элементы из списка, предотвращая их сохранены в базе данных.

Так Джим , который не является менеджером, может попытаться сохранить список задач, некоторые из которых назначены Пэм . Однако только те задачи, которые возложены Джим будут включены, остальные будут проигнорированы.

4. Производительность в больших списках

@PreFilter действительно здорово и просто в использовании, но это может быть неэффективным при работе с очень большими списками, так как операция извлечения будет получить все данные и применить фильтр потом.

Представьте себе, например, что у нас есть тысячи задач в нашей базе данных, и мы хотим, чтобы получить пять задач, которые в настоящее время назначены Пэм . Если мы используем @PreFilter , операция базы данных будет приносить все задачи в первую очередь, и итерировать через все из них, чтобы отфильтровать те, которые не назначены Пэм .

5. Заключение

В этой быстрой статье объясняется, как создать простое, но безопасное приложение с помощью приложения Spring Security @PreFilter и @PostFilter Аннотации.

Проверьте полный пример кода в этом репозитории Github .