Я создаю приложение, используя Spring Data Rest
, Spring Boot
и Spring Security
. Мне нужно использовать @Secured
аннотации о методах и я настроил Spring Security
следующим образом:Весна Данные Отдых + Весна Безопасность: @ Обязательно не работает
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// @formatter:off
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.securityContext().securityContextRepository(securityContextRepository())
.and()
.exceptionHandling()
.accessDeniedPage(RestPath.Errors.ROOT + RestPath.Errors.FORBIDDEN)
.and()
.csrf().disable();
}
// @formatter:on
@Bean
public SecurityContextRepository securityContextRepository() {
return new ApiUserSecurityContextRepository();
}
@Bean
public UserDetailsService userDetailsService() {
return new ApiUserDetailsService();
}
@Bean
public AuthenticationManager authenticationManager() throws Exception {
return new ProviderManager(Collections.singletonList(authenticationProvider()));
}
@Bean
public AuthenticationProvider authenticationProvider() throws Exception {
final DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Этот тип конфигурации работает хорошо для обычных контроллеров MVC и возвращает 403 при попытке доступа к ним. Например, следующая безопасность контроллера работает:
@ResponseBody
@RequestMapping(value = RestPath.Configs.SLASH_TEST, method = RequestMethod.GET, produces = MediaTypes.HAL_JSON_VALUE)
@Secured({"ROLE_USER"})
public ResponseEntity test(@RequestParam(value = RestParam.DB_TEST, required = false) final boolean dbTest) throws ApplicationAvailabilityException {
final AppTestData appTestData = configService.testAppAvailability(dbTest);
return ResponseEntity.ok(projectionFactory.createProjection(AppTestProjection.class, appTestData));
}
Однако, когда я пытаюсь использовать @Secured аннотации над хранилищем отдыха - это не делает, например:
@RepositoryRestResource(collectionResourceRel = Shop.COLLECTION_NAME, path = RestResourceRel.SHOPS, excerptProjection = StandardShopProjection.class)
@Secured({"ROLE_USER"})
public interface RestShopRepository extends MongoRepository<Shop, String> {
@Secured({"ROLE_ADMIN"})
@Override
Shop findOne(String s);
}
ApiUserSecurityContextRepository
является вызывался для обоего методов, но только пользовательский контроллер MVC доходит до конца цепи, и я могу проверить, что он обращается к методу vote()
в классе RoleVoter
для предоставления доступа. В качестве примера я проверил образец Spring Data Rest + Spring Security, поэтому @Secured
или @PreAuthorize
аннотации должны работать с Spring Data Rest
. Любые идеи, почему они не работают?
Как вы получаете доступ к защищенному репозиториюRestResource из своих модулей безопасности? Предположим, вы хотите запросить пользователя по имени пользователя из UserDetailsService - вы хотите сделать это в виде божественного режима вместо использования учетных данных, предоставляемых сеансом HTTP. – Piotr
@ Петр не уверен, что правильно понял ваш вопрос. Почему учетные данные, предоставленные сеансом HTTP, не будут работать? –
Предположим, что пользователь с ролью USER выполняет запрос. Вы хотите посмотреть его в пользовательском репозитории в некотором методе фильтра безопасности, таком как loadUserByUsername, поэтому вы вызываете метод запроса findByUsername. Но этот метод аннулируется hasRole (ADMIN), который приводит к несанкционированному доступу, поскольку весна выполняет его с учетными данными Роль USER. Так понятно? – Piotr