Spring 数据休息 + Spring 安全:@Secured 不工作
Spring Data Rest + Spring Security: @Secured not working
我正在使用 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 控制器和 returns 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));
}
但是,当我尝试在 rest 存储库上使用 @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
class 用于授予访问权限。
例如,我检查了 Spring Data Rest + Spring Security 示例,因此 @Secured
或 @PreAuthorize
注释应该与 Spring Data Rest
一起使用。知道为什么它们不起作用吗?
问题终于解决了。问题出在下面,我在不同的应用程序模块中有另一个 ShopRepository
,它没有用 @RepositoryRestResource
注释,它是使用 REST 访问它时使用的那个。
自定义中的以下配置行 RepositoryRestConfigurerAdapter
修复了需要公开的存储库的探索,因此现在只公开注释的:
config.setRepositoryDetectionStrategy(RepositoryDetectionStrategy.RepositoryDetectionStrategies.ANNOTATED);
在那之后我根本无法使用 REST 访问该资源,所以我发现它对 Spring
不可见。我只需要在 API 级别启用 Mongo 存储库,注释 @EnableMongoRepositories
.
我正在使用 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 控制器和 returns 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));
}
但是,当我尝试在 rest 存储库上使用 @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
class 用于授予访问权限。
例如,我检查了 Spring Data Rest + Spring Security 示例,因此 @Secured
或 @PreAuthorize
注释应该与 Spring Data Rest
一起使用。知道为什么它们不起作用吗?
问题终于解决了。问题出在下面,我在不同的应用程序模块中有另一个 ShopRepository
,它没有用 @RepositoryRestResource
注释,它是使用 REST 访问它时使用的那个。
自定义中的以下配置行 RepositoryRestConfigurerAdapter
修复了需要公开的存储库的探索,因此现在只公开注释的:
config.setRepositoryDetectionStrategy(RepositoryDetectionStrategy.RepositoryDetectionStrategies.ANNOTATED);
在那之后我根本无法使用 REST 访问该资源,所以我发现它对 Spring
不可见。我只需要在 API 级别启用 Mongo 存储库,注释 @EnableMongoRepositories
.