Webflux - Spring Boot - 具有 http 代理支持的 oAuth2 客户端
Posted
技术标签:
【中文标题】Webflux - Spring Boot - 具有 http 代理支持的 oAuth2 客户端【英文标题】:Webflux - Spring Boot - oAuth2 client with http proxy support 【发布时间】:2020-02-23 04:46:19 【问题描述】:我正在努力在代理后面使用 oauth2 正确设置 webflux-weblient。
看来, ServerOAuth2AuthorizedClientExchangeFilterFunction 使用了一个新的 webclient 实例,它不包含我的代理配置。
OAuth2-配置
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth2ClientFilter = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrations,
new UnAuthenticatedServerOAuth2AuthorizedClientRepository());
oauth2ClientFilter.setDefaultClientRegistrationId("azure");
OAuth2AuthorizedClientResolver.class 包含:
private ReactiveOAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> clientCredentialsTokenResponseClient = new WebClientReactiveClientCredentialsTokenResponseClient();
WebClientReactiveClientCredentialsTokenResponseClient.java
创建一个新的网络客户端如下:
private WebClient webClient = WebClient.builder().build();
是否有人有示例如何为 oauth2 客户端正确设置 http 代理?
【问题讨论】:
你找到解决办法了吗? 你试过@jocker提到的解决方案吗??? 【参考方案1】:感谢@abhinaba-chakraborty 的不完整回答,我设法根据WebClient
中的JVM 参数为WebClientReactiveClientCredentialsTokenResponseClient
设置代理。
这是我的代码片段,可以帮助其他有同样问题的人:
这是一个辅助函数,用于获取 JVM 参数并将它们设置为 HttpClient
public HttpClient proxyHttpClient()
String proxyHost = System.getProperty("https.proxyHost");
String proxyPort = System.getProperty("https.proxyPort");
if (proxyHost == null && proxyPort == null)
return HttpClient.create();
return HttpClient.create()
.tcpConfiguration(tcpClient ->
tcpClient.proxy(proxy ->
proxy.type(ProxyProvider.Proxy.HTTP).host(proxyHost).port(Integer.valueOf(proxyPort))
)
);
这是为用于调用外部系统的WebClient
配置OAuth2Client 的方法(基于@abhinaba-chakraborty 的响应)。注意名为configureHttpProxy
的函数:
@Bean
public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
ReactiveClientRegistrationRepository clientRegistrationRepository,
ReactiveOAuth2AuthorizedClientService authorizedClientService)
return configureHttpProxy(
new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
clientRegistrationRepository,
authorizedClientService
)
);
@Bean
WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager)
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth2Client = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oauth2Client.setDefaultClientRegistrationId("registration_id");
return WebClient.builder()
.filter(oauth2Client)
.clientConnector(new ReactorClientHttpConnector(HttpClient.create().wiretap(true)))
.baseUrl(rdoWebClientProperties.getBaseUrl())
.defaultHeader(rdoWebClientProperties.getApikeyName(), rdoWebClientProperties.getApikeyValue())
.build();
这里是configureHttpProxy
函数:
private AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager configureHttpProxy(AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager)
// set the webclient with proxy configuration in the ReactiveOAuth2AccessTokenResponseClient
WebClientReactiveClientCredentialsTokenResponseClient tokenResponseClient = new WebClientReactiveClientCredentialsTokenResponseClient();
tokenResponseClient.setWebClient(
WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(proxyHttpClient()))
.build()
);
// set the ReactiveOAuth2AccessTokenResponseClient with webclient configuration in the ReactiveOAuth2AuthorizedClientProvider
ClientCredentialsReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = new ClientCredentialsReactiveOAuth2AuthorizedClientProvider();
authorizedClientProvider.setAccessTokenResponseClient(tokenResponseClient);
// set the ReactiveOAuth2AuthorizedClientProvider in the ReactiveOAuth2AuthorizedClientManager
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
希望这会有所帮助。
【讨论】:
【参考方案2】:对于 OAuth2.0 客户端凭据流,在 web 安全配置中,您需要以下内容:
@EnableWebFluxSecurity
public class WebSecurityConfiguration
@Bean
public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
ReactiveClientRegistrationRepository clientRegistrationRepository,
ReactiveOAuth2AuthorizedClientService authorizedClientService)
ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();
AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
@Bean
public WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager)
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
return WebClient.builder().filter(oauth).build();
现在进行实际的 API 调用:
webClient.get()
.uri(<protected resource uri which you want to access>)
.attributes(clientRegistrationId(<The Provider name specified under registration in app yaml>))
.retrieve()
.bodyToMono(String.class)
.map(string
-> "Retrieved using Client Credentials Grant Type: " + string)
.subscribe(LOGGER::info);
供您参考,我使用的是 Spring Boot 版本 2.3.1.RELEASE 我的 application.yaml 看起来像这样:
spring:
security:
oauth2:
client:
provider:
<provider-name>:
issuer-uri: <issuer-uri implementing OIDC>
registration:
<provider-name>:
client-id: <client-id>
client-secret: <client-secret>
scope: <comma separated scopes>
authorization-grant-type: client_credentials
【讨论】:
谢谢,但我在您的示例中看不到任何代理配置...正如问题中提到的那样,这是这里的问题...以上是关于Webflux - Spring Boot - 具有 http 代理支持的 oAuth2 客户端的主要内容,如果未能解决你的问题,请参考以下文章
服务器使用 Spring Boot 和 WebFlux 发送事件
原始性能表格 - Spring Boot 2 Webflux vs. Spring Boot 1
Spring Boot Webflux/Netty - 检测关闭的连接
如何在 Spring boot 2 + Webflux + Thymeleaf 中配置 i18n?