Как правильно получить доступ к защищенному REST-репозиторию Spring Data в ApplicationRunner? - PullRequest
0 голосов
/ 24 апреля 2020

Я следовал документации о том, как защитить REST-репозитории с помощью @PreAuthorize. Тем не менее, ApplicationRunner должен выполнить доступ к следующему репозиторию

@PreAuthorize("hasRole('ROLE_ADMIN')")
@RepositoryRestResource
public interface RouteRepository extends SortingOnlyRepository<Route, Long> {
}

для выполнения некоторых задач начальной настройки после запуска приложения.

@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 как это
  • Отделить проблемы и просто не использовать REST репозиторий для этого варианта использования
  • Настройка безопасности только за WebSecurityConfig

1 Ответ

0 голосов
/ 29 апреля 2020

Ответ на вопрос заключается в заполнении правильного (поддельного) контекста безопасности, который фактически приводится в официальном примере 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)));
}
...