Spring Data Rest + Spring Security:@Secured无法正常工作

时间:2016-10-19 11:28:20

标签: java spring spring-mvc spring-security spring-data-rest

我正在使用Spring Data RestSpring BootSpring 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 个答案:

答案 0 :(得分:1)

终于解决了这个问题。问题出现在下面,我在不同的应用程序模块中有另一个ShopRepository,它没有用@RepositoryRestResource注释,而是使用REST访问它时使用的那个。

自定义RepositoryRestConfigurerAdapter中的以下配置行修复了需要公开的存储库的探索,因此现在只公开注释:

config.setRepositoryDetectionStrategy(RepositoryDetectionStrategy.RepositoryDetectionStrategies.ANNOTATED);

之后我根本无法使用REST访问资源,所以我发现它Spring不可见。我只需要在API级别上使用注释@EnableMongoRepositories启用Mongo存储库。