Spring Data Rest: проектирование на основе безопасности

17

Я использую текущую версию Spring Data Rest и Spring Data 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 для разные запросы.

Затем я нашел

и еще один подробный:

@Projection(name = "detailed", types = User.class)
public interface UserDetailProjection extends UserSimpleProjection{

    public String getEmail();
}

Пока все хорошо, я получаю разные результаты в зависимости от моего запроса.

Есть ли способ автоматически переключать проекцию в зависимости от Spring Security и / или ограничивать разные прогнозы для разных ролей?

    
задан Plechi 01.03.2015 в 14:37
источник
  • Вы случайно не смогли создать роль проекций? –  ArunM 06.06.2015 в 18:22
  • Нет, извините. Тогда я сдался и сделал пользовательские контроллеры. –  Plechi 06.06.2015 в 23:04

3 ответа

14

В проекцию можно добавить свойство «виртуального» значения, которое вызывает метод службы с проверками безопасности:

@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.

    
ответ дан aux 14.02.2016 в 23:56
  • Вот и все! Благодаря! –  Plechi 18.02.2016 в 23:05
  • почему это не работает @Value ("# {main.username.equalsIgnoreCase ('admin')? target.password: null}") –  ArslanAnjum 11.05.2017 в 09:24
  • Поскольку принципал не является свойством корневого объекта SpEL, используемого в этом контексте. Для доступа к bean-компоненту вы можете использовать префикс @. Pls читает больше о SpEL: docs.spring.io/spring/docs/current/spring-framework-reference/... –  aux 11.05.2017 в 17:14
  • Обратите внимание, что в SPeL вы можете использовать переменные (#myvar), beans (@mybean), свойства и методы «root object» и т. д. Также обратите внимание, что выражения имеют разные «корневые объекты» в разных контекстах, которые задаются некоторыми обработчик. Например. @PreAuthorize обрабатывается методом MethodSecurityExpressionHandler, а проекция @Value - с помощью SpelAwareProxyProjectionFactory. Вы можете проверить исходный код для справки. –  aux 11.05.2017 в 17:46
1

Вы также можете сделать это, используя RegexRequestMatcher в вашем конфигураторе Spring Security, например:

.regexMatchers(HttpMethod.GET,"/user/.*projection=simple.*").hasRole("ROLE_ADMIN")
    
ответ дан Sparm 09.03.2017 в 09:59
0

Нет, Spring REST-прогнозы не поддерживают это.

    
ответ дан Willie Wheeler 12.01.2016 в 08:29