Spring Security 5 Вызов OAuth2 Обеспеченные API в Application Runner приводит к IllegalArgumentException

Даррен Форсайт:

Учитывая следующий код, это можно вызвать учетные данные клиента, обеспеченные API в бегуна приложений?

@Bean
public ApplicationRunner test(
    WebClient.Builder builder,
    ClientRegistrationRepository clientRegistrationRepo, 
    OAuth2AuthorizedClientRepository authorizedClient) {
        return args -> {
            try {
                var oauth2 =
                    new ServletOAuth2AuthorizedClientExchangeFilterFunction(
                        clientRegistrationRepo,
                        authorizedClient);
                oauth2.setDefaultClientRegistrationId("test");
                var response = builder
                    .apply(oauth2.oauth2Configuration())
                    .build()
                    .get()
                    .uri("test")
                    .retrieve()
                    .bodyToMono(String.class)
                    .block();
                log.info("Response - {}", response);
            } catch (Exception e) {
                log.error("Failed to call test.", e);
            }
        };
    }

Код не из-за,

java.lang.IllegalArgumentException: request cannot be null

Полный стек,

java.lang.IllegalArgumentException: request cannot be null
    at org.springframework.util.Assert.notNull(Assert.java:198) ~[spring-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizedClientRepository.loadAuthorizedClient(HttpSessionOAuth2AuthorizedClientRepository.java:47) ~[spring-security-oauth2-client-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    at org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction.populateDefaultOAuth2AuthorizedClient(ServletOAuth2AuthorizedClientExchangeFilterFunction.java:364) ~[spring-security-oauth2-client-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    at org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction.lambda$null$2(ServletOAuth2AuthorizedClientExchangeFilterFunction.java:209) ~[spring-security-oauth2-client-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    at org.springframework.web.reactive.function.client.DefaultWebClient$DefaultRequestBodyUriSpec.attributes(DefaultWebClient.java:234) ~[spring-webflux-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.reactive.function.client.DefaultWebClient$DefaultRequestBodyUriSpec.attributes(DefaultWebClient.java:153) ~[spring-webflux-5.1.5.RELEASE.jar:5.1.5.RELEASE]

С методами не суметь похожие,

public <T extends OAuth2AuthorizedClient> T loadAuthorizedClient(
    String clientRegistrationId,  Authentication principal, HttpServletRequest request){

    Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
    Assert.notNull(request, "request cannot be null");
    return (OAuth2AuthorizedClient)this
        .getAuthorizedClients(request)
        .get(clientRegistrationId);
}

Который имеет смысл , поскольку не существует HttpServletRequestдля того , чтобы использовать, его называют при запуске приложения.

Есть ли обходные пути, кроме сделать свой не-оп OAuth2AuthorizedClientRepository?

//Редактировать,

Это не полностью реактивная стек. Это стек Spring Web с WebClient используется с в нем.

Я хорошо осведомлен о ServerOAuth2AuthorizedClientExchangeFilterFunctionкоторой относится к полностью реактивной стеке и требуют ReactiveClientRegistrationRepositoryи ReactiveOauth2AuthorizedClientкоторые не доступны из - за этого существо в приложении , построенное на вершине стека Servlet, а не реактивный.

Scorpioo590:

Так как я наткнулся на этой проблеме , я разработать немного на Даррен Форсайт обновленного ответа , чтобы сделать его проще для других , чтобы найти:

Вопрос , представленный ОР в результате реализация OAuth2AuthorizedClientManager, которая способна

работающие вне контекста HttpServletRequest, например, в запланированном / фоновом потоке и / или в сервисном ярусе

( Из официальных документов )

Указанная реализация, то AuthorizedClientServiceOAuth2AuthorizedClientManager, передается в ServletOAuth2AuthorizedClientExchangeFilterFunctionзаменить один по умолчанию.

В моем примере это выглядит примерно так:

@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
        ClientRegistrationRepository clientRegistrationRepository,
        OAuth2AuthorizedClientService clientService)
{

    OAuth2AuthorizedClientProvider authorizedClientProvider = 
        OAuth2AuthorizedClientProviderBuilder.builder()
            .clientCredentials()
            .build();

    AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager = 
        new AuthorizedClientServiceOAuth2AuthorizedClientManager(
            clientRegistrationRepository, clientService);
    authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

    return authorizedClientManager;
}

@Bean
WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager)
{
    ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 =
        new ServletOAuth2AuthorizedClientExchangeFilterFunction(
            authorizedClientManager);
    oauth2.setDefaultClientRegistrationId("keycloak");
    return WebClient.builder().apply(oauth2.oauth2Configuration()).build();
}

рекомендация

отhttp://43.154.161.224:23101/article/api/json?id=138163&siteId=1
рекомендация