如何在 ApplicationRunner 中正确访问受保护的 Spring 数据 REST 存储库?
How to properly access a secured Spring Data REST Repository in a ApplicationRunner?
我按照 documentation 了解如何使用 @PreAuthorize
保护 REST 存储库。但是,以下存储库
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RepositoryRestResource
public interface RouteRepository extends SortingOnlyRepository<Route, Long> {
}
需要由 ApplicationRunner
访问以在应用程序启动后执行一些初始设置任务。
@Component
public class RouteBuilder implements ApplicationRunner {
private final RouteRepository repository;
public RouteBuilder(RouteRepository repository) {
this.repository = repository;
}
@Override
public void run(ApplicationArguments args) throws Exception {
repository.findAll()
.stream()
// do something
;
}
}
由于执行此运行程序时没有活动的安全上下文,因此应用程序根本不会启动
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: java.lang.IllegalStateException: Failed to execute ApplicationRunner
Caused by: org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
我有哪些正确访问 REST 存储库的选项?我在考虑
- 填充一个 假
Authentication
像 this
- 解耦问题,只是不要为此用例使用 REST 存储库
- 单独配置
WebSecurityConfig
中的安全性
问题的答案是填充适当的(假的)安全上下文,并且实际上在官方 Spring Data REST + Spring Security 示例中给出。
改编自Application
:
try {
SecurityUtils.runAs("system", "system", "ROLE_ADMIN");
repository.findAll()
.stream()
// do something
;
} finally {
SecurityContextHolder.clearContext();
}
其中 SecurityUtils
是
public static void runAs(String username, String password, String... roles) {
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(username, password, AuthorityUtils.createAuthorityList(roles)));
}
我按照 documentation 了解如何使用 @PreAuthorize
保护 REST 存储库。但是,以下存储库
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RepositoryRestResource
public interface RouteRepository extends SortingOnlyRepository<Route, Long> {
}
需要由 ApplicationRunner
访问以在应用程序启动后执行一些初始设置任务。
@Component
public class RouteBuilder implements ApplicationRunner {
private final RouteRepository repository;
public RouteBuilder(RouteRepository repository) {
this.repository = repository;
}
@Override
public void run(ApplicationArguments args) throws Exception {
repository.findAll()
.stream()
// do something
;
}
}
由于执行此运行程序时没有活动的安全上下文,因此应用程序根本不会启动
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: java.lang.IllegalStateException: Failed to execute ApplicationRunner
Caused by: org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
我有哪些正确访问 REST 存储库的选项?我在考虑
- 填充一个 假
Authentication
像 this - 解耦问题,只是不要为此用例使用 REST 存储库
- 单独配置
WebSecurityConfig
中的安全性
问题的答案是填充适当的(假的)安全上下文,并且实际上在官方 Spring Data REST + Spring Security 示例中给出。
改编自Application
:
try {
SecurityUtils.runAs("system", "system", "ROLE_ADMIN");
repository.findAll()
.stream()
// do something
;
} finally {
SecurityContextHolder.clearContext();
}
其中 SecurityUtils
是
public static void runAs(String username, String password, String... roles) {
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(username, password, AuthorityUtils.createAuthorityList(roles)));
}