spring webclient未将代理服务器与spring-security-oauth2-client-5.4.6一起使用

ie3xauqp  于 2021-09-29  发布在  Java
关注(0)|答案(0)|浏览(270)

我必须迁移现有的 OAuth2RestTemplate 基于oauth2微服务的spring security/ WebClient 因为 OAuth2RestTemplate 不推荐使用。但是,新的实现无法通过代理服务器访问oauth2服务器。我已经阅读了关于这个主题的各种文章,包括spring webclient没有为最新版本的spring-security-oauth2-client-5.3.4.release使用代理,并尝试将这些文章中描述的逻辑包括在我的实现中。不幸的是没有成功。我的实现配置了底层 ClientHttpConnector 被使用 WebClient 使用适当的代理设置。请参阅下面的代码片段 WebClientConfig (完整的代码库包括 WebClientConfig 单元测试可以在这里找到:github):

@Bean
  public ReactiveClientRegistrationRepository clientRegistrationRepository() {
    ClientRegistration clientRegistration = ClientRegistration
        .withRegistrationId(REGISTRATION_ID)
        .authorizationGrantType(AuthorizationGrantType.PASSWORD)
        .clientId(CLIENT_ID)
        .clientSecret(CLIENT_SECRET)
        .clientAuthenticationMethod(ClientAuthenticationMethod.POST)
        .userInfoAuthenticationMethod(AuthenticationMethod.FORM)
        .tokenUri(restServiceProperties.getOauth2Url())
        .build();
    return new InMemoryReactiveClientRegistrationRepository(clientRegistration);
  }
@Bean
  public ReactiveOAuth2AuthorizedClientService authorizedClientService(ReactiveClientRegistrationRepository clientRegistrationRepository) {
    return new InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrationRepository);
  }
@Bean
  public ClientHttpConnector clientHttpConnector() {
    HttpAsyncClientBuilder clientBuilder = HttpAsyncClients.custom();
    if (Strings.isNotEmpty(restServiceProperties.getProxyUrl())) {
      try {
        HttpHost proxy = HttpHost.create(restServiceProperties.getProxyUrl());
        clientBuilder.setRoutePlanner(new DefaultProxyRoutePlanner(proxy));
      } catch (URISyntaxException e) {
        log.error("Error: {}", e.getMessage());
        throw new RuntimeException(e);
      }
    }
    CloseableHttpAsyncClient client = clientBuilder.build();
    return new HttpComponentsClientHttpConnector(client);
  }
@Bean
  public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(ReactiveClientRegistrationRepository clientRegistrationRepository,
      ReactiveOAuth2AuthorizedClientService authorizedClientService, ClientHttpConnector clientHttpConnector, WebClient.Builder webClientBuilder) {

    WebClient webClient = webClientBuilder
        .clientConnector(clientHttpConnector)
        .filter(logRequest())
        .build();

    AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager = new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
        clientRegistrationRepository, authorizedClientService);
    authorizedClientManager.setAuthorizedClientProvider(createAuthorizedClientProvider(webClient));
    authorizedClientManager.setContextAttributesMapper(request -> {
      Map<String, Object> contextAttributes = new HashMap<>();
      contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, USER);
      contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, PASSWORD);
      return Mono.just(contextAttributes);
    });

    return authorizedClientManager;
  }
@Bean
  public WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager,
      ClientHttpConnector clientHttpConnector, WebClient.Builder webClientBuilder) {

    ServerOAuth2AuthorizedClientExchangeFilterFunction oauth2FilterFunction = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
    oauth2FilterFunction.setDefaultClientRegistrationId(REGISTRATION_ID);

    return webClientBuilder
        .clientConnector(clientHttpConnector)
        .filters(exchangeFilterFunctions -> {
          exchangeFilterFunctions.add(oauth2FilterFunction);
          exchangeFilterFunctions.add(logRequest());
        })
        .build();
  }
private ReactiveOAuth2AuthorizedClientProvider createAuthorizedClientProvider(WebClient webClient) {
    WebClientReactiveClientCredentialsTokenResponseClient clientCredentialsTokenResponseClient = new WebClientReactiveClientCredentialsTokenResponseClient();
    clientCredentialsTokenResponseClient.setWebClient(webClient);
    return ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
        .clientCredentials(builder -> builder.accessTokenResponseClient(clientCredentialsTokenResponseClient))
        .password()
        .refreshToken()
        .build();
  }
private ExchangeFilterFunction logRequest() {
    return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
      log.info("Request: method: {} URL: {}", clientRequest.method(), clientRequest.url());
      clientRequest.headers().forEach((name, values) -> values.forEach(value -> log.info("Request header: name: {} value: {}", name, value)));
      return Mono.just(clientRequest);
    });
  }

我也试过了 clientBuilder.setProxy(proxy) 而不是 clientBuilder.setRoutePlanner(new DefaultProxyRoutePlanner(proxy)) ,但这并没有解决问题。
关于单元测试: NoProxyServerTest 显示在未配置代理服务器时可以访问oauth2服务器和下游服务器。 ProxyServerTest 显示在配置代理服务器时无法访问oauth2服务器。 DirectProxyServerInvocationTest 表明 MockProxyServer 它实际上在工作。及 DownstreamServerProxyServerInvocationTest 显示可以通过代理服务器访问下游服务器。 WebClient 在中配置 WebClientConfig . 这可能是迄今为止最好的配置,但我尝试了许多不同的配置来解决这个代理服务器问题(包括使用 https.proxyPort , https.proxyHost , http.proxyPorthttp.proxyHost ).
正在使用类似的测试来测试不推荐使用的oauth2resttemplate实现。所有四个测试都通过了该实现。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题