java - 如何在 ApplicationRunner 中正确访问安全的 Spring Data REST 存储库?

标签 java spring spring-data-rest

我关注了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
                ;
    }
}

由于执行此运行程序时没有 Activity 的安全上下文,因此应用程序根本不会启动

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 存储库?我在想

  • 填充一个身份验证,例如 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)));
}

关于java - 如何在 ApplicationRunner 中正确访问安全的 Spring Data REST 存储库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61411411/

相关文章:

java - 使用本地库覆盖 Maven 依赖项

java - POJO 不相关或不可用时的 HQL 查询

java - 如何使用Spring创建一个父接口(interface),其中包含子接口(interface)的一些注释?

java - 如何将两个 jrxml jasper 报告合并为一个 pdf 输出文件

Spring 的 DI 不是 transient 的,也不是可序列化的,而是记录 NSE

java - 为什么以下带有 mongodb 的 Spring Boot + HATEOAS 不起作用(MarshalException)?

java - Spring如何保留@Controller生成的json中所有子实体的实体id?

java - 将 spring-data-rest-repository 添加到 spring-data-rest-webmvc

java - 如何隐藏 Steam Web API key ?

日语字符的Java编码