Включение защиты объектов домена @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/

Другие вопросы по тегам