Spring Сохранение данных: прогноз на основе безопасности
Я использую текущую версию Spring Data Rest и Spring Данные JPA и имеют следующую структуру:
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
private String password;
private String email;
...getter/setter methods...
}
Я также использую Spring Security
.
Мой репозиторий пользователя:
@RepositoryRestResource(
collectionResourceRel = "user",
path = "user",
excerptProjection = UserSimpleProjection.class)
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
}
Пример:
- Пользователь 1 зарегистрирован
- Пользователь 1 запрос
http://localhost:8080/user/1
- все поля видны
- Пользовательские запросы 1
http://localhost:8080/user/2
- просто id
и name
видны.
Я пробовал разные решения с Jackson, ни одна из них не решила мою проблему:
- Использование JsonView: я не нашел способа изменить вид для
ObjectMapper
в зависимости от зарегистрированного пользователя
- Реализованы различные фильтры Джексона, как описано здесь с той же проблемой, что я не нашел способа изменить конфигурацию
ObjectMapper
для разных запросов.
Затем я нашел Projections.
Я создал проекцию:
@Projection(name = "simple", types = User.class)
public interface UserSimpleProjection {
public Long getId();
public String getName();
}
и еще один подробный:
@Projection(name = "detailed", types = User.class)
public interface UserDetailProjection extends UserSimpleProjection{
public String getEmail();
}
Пока все хорошо, я получаю разные результаты в зависимости от моего запроса.
Есть ли способ автоматически переключать проекцию в зависимости от Spring Безопасность и/или ограничивать разные прогнозы для разных ролей?
Ответы
Ответ 1
В проекцию можно добавить свойство "виртуального" значения, которое вызывает метод службы с проверками безопасности:
@Projection(name = "detailed", types = User.class)
public interface UserDetailProjection extends UserSimpleProjection{
@Value("#{@userService.checkAccess(target)? target.email : null}")
public String getEmail();
}
Если ваш пользовательский компонент UserService
вернет true
, если электронное письмо должно быть открыто или просто @PreAuthorize
на checkAccess(..)
, чтобы выбросить AccessDeniedException
, что лучше для вас.
Обратите внимание, что свойство target
в SpEL содержит исходный объект, предоставленный Spring -DATA.
Ответ 2
Вы также можете сделать это с помощью RegexRequestMatcher в вашем конфигураторе безопасности Spring следующим образом:
.regexMatchers(HttpMethod.GET,"/user/.*projection=simple.*").hasRole("ROLE_ADMIN")
Ответ 3
Нет, Spring Прогнозы данных REST не поддерживают это.