2016-10-19 2 views
0

Я создаю приложение, используя 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. Любые идеи, почему они не работают?

ответ

1

Наконец-то решила проблему. Проблема заключалась в следующем: у меня был еще один ShopRepository в другом прикладном модуле, который не был аннотирован @RepositoryRestResource, и он был тем, который использовался при доступе к нему с помощью REST.

Следующая строка конфигурации в пользовательских RepositoryRestConfigurerAdapter исправили исследование хранилищ, которые должны быть выставлены, поэтому только аннотированные те подвергаются в настоящее время:

config.setRepositoryDetectionStrategy(RepositoryDetectionStrategy.RepositoryDetectionStrategies.ANNOTATED); 

После этого я не мог получить доступ к ресурсу на все с помощью REST , поэтому я понял, что он не виден Spring. Мне просто пришлось включить репозитории Mongo на уровне API с аннотацией @EnableMongoRepositories.

+0

Как вы получаете доступ к защищенному репозиториюRestResource из своих модулей безопасности? Предположим, вы хотите запросить пользователя по имени пользователя из UserDetailsService - вы хотите сделать это в виде божественного режима вместо использования учетных данных, предоставляемых сеансом HTTP. – Piotr

+0

@ Петр не уверен, что правильно понял ваш вопрос. Почему учетные данные, предоставленные сеансом HTTP, не будут работать? –

+0

Предположим, что пользователь с ролью USER выполняет запрос. Вы хотите посмотреть его в пользовательском репозитории в некотором методе фильтра безопасности, таком как loadUserByUsername, поэтому вы вызываете метод запроса findByUsername. Но этот метод аннулируется hasRole (ADMIN), который приводит к несанкционированному доступу, поскольку весна выполняет его с учетными данными Роль USER. Так понятно? – Piotr

Смежные вопросы