Включение защиты объектов домена @PostFilter в репозитории Spring Data.
В моем проекте я использую Spring-Data, Spring-Data-Rest и Spring-Security.
Что мне нужно сделать, это реализовать защиту объектов домена (ACL) в этих хранилищах. Specificaly @PostFilter
над Pageable.findAll()
метод.
Безопасность на уровне метода легко реализуется, как описано здесь.
В документации также есть раздел об использовании выражения безопасности с @Query
здесь
Но хотя я могу использовать hasPermission(..)
метод внутри @Query
также нет способа включить объект (строку SQL) в этот метод - чтобы быть точным, сделайте это:
@Query("select u from #{#entityName} u where 1 = ?#{security.hasPermission(u, 'read') ? 1 : 0}")
Теперь я понимаю, что это сильно отличается от изменения предварительного выполнения запроса, например:
@Query("select m from Message m where m.to.id = ?#{ principal?.id }")
Я также обнаружил следующую проблему jira: https://jira.spring.io/browse/DATACMNS-293 которая, как я подозреваю, как только она будет решена, найдет решение, но не похоже, что оно будет в любое время скоро.
Мне все еще нужно реализовать эту функциональность, и для этого я хотел бы получить ваш вклад и указания на возможные решения.
Прямо сейчас я думаю о создании моей собственной аннотации, которая будет имитировать @PostFilter
один и использовать тот же синтаксис, но будет вызываться вручную внутри моей собственной BaseRepositoryImplementation. Там я получу интерфейс хранилища от типа и Repositories#getRepositoryInformationFor(type)#getRepositoryInterface()
найдите аннотацию к соответствующему методу и вручную вызовите проверку безопасности.
Возможно, у вас есть другое решение или какие-нибудь заметки о моем предложенном решении?
Кроме того, вы случайно не знаете, есть ли расписание по упомянутому вопросу джиры?
1 ответ
Один из легких способов сделать это - использовать метод hasPermission() и реализовать собственный "Оценщик разрешений" на уровне контроллера, если это вариант для вас.
@PreAuthorize("hasPermission(#employee, 'edit')")
public void editEmployee(Employee employee) {
...
}
@Component
public class PermissionEvaluatorImpl implements PermissionEvaluator {
@Override
public boolean hasPermission(Authentication auth,
Object targetDomainObject, Object permission) {
// return true if "auth" has "permission" permission for the user.
// Current-user can be obtained from auth.
}
...
}
Это описано более подробно здесь: http://www.naturalprogrammer.com/spring-domain-object-security-logged-in-user/