企业代理环境下能否搭配Okta使用JHipster响应式网关?
该问题是企业内网代理环境下部署Spring WebFlux OAuth2应用的高频问题,核心原因是WebFlux底层默认使用的Reactor Netty客户端不会主动读取JVM系统代理或操作系统代理配置,也没有开箱即用的代理配置项,和Spring MVC的RestTemplate行为不一致。JHipster生成的网关默认使用WebClient与Okta进行OAuth2交互,未配置代理的情况下就会返回connection refused错误。
- 方案1:自定义WebClient为Okta请求注入代理配置
这是最精准的方案,只会代理到Okta的请求,不会影响其他业务流量。首先在生产环境配置文件中新增代理配置项:
proxy: okta: host: 内部代理服务器地址 port: 代理端口 # 代理需要认证时补充以下两项 username: 代理认证用户名 password: 代理认证密码
新增对应配置类和自定义WebClient实例:
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction; import org.springframework.security.oauth2.client.web.server.UnAuthenticatedServerOAuth2AuthorizedClientRepository; import org.springframework.web.reactive.function.client.WebClient; import reactor.netty.http.client.HttpClient; import reactor.netty.transport.ProxyProvider; @Configuration @EnableConfigurationProperties(OktaProxyConfig.class) public class OktaProxyConfiguration { @Bean public WebClient oktaWebClient(ReactiveClientRegistrationRepository clientRegistrationRepository, OktaProxyConfig proxyConfig) { // 构造带代理的Netty HttpClient HttpClient httpClient = HttpClient.create() .proxy(proxySpec -> proxySpec.type(ProxyProvider.Proxy.HTTP) .host(proxyConfig.getOkta().getHost()) .port(proxyConfig.getOkta().getPort()) // 代理需认证时启用以下配置 .username(proxyConfig.getOkta().getUsername()) .password(pwdSupplier -> proxyConfig.getOkta().getPassword())); ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient); ServerOAuth2AuthorizedClientExchangeFilterFunction oauthFilter = new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrationRepository, new UnAuthenticatedServerOAuth2AuthorizedClientRepository()); oauthFilter.setDefaultClientRegistrationId("okta"); return WebClient.builder() .clientConnector(connector) .filter(oauthFilter) .build(); } @ConfigurationProperties(prefix = "proxy") public record OktaProxyConfig(OktaInfo okta) { public record OktaInfo(String host, Integer port, String username, String password) {} } }
替换JHipster网关中所有和Okta交互的WebClient实例为上述自定义的oktaWebClient即可生效。
方案2:全局配置Reactor Netty代理参数
如果所有对外请求都需要走内部代理,可以直接添加JVM启动参数实现,无需修改代码:-Dreactor.netty.http.client.proxyHost=代理地址 -Dreactor.netty.http.client.proxyPort=代理端口 -Dreactor.netty.http.client.proxyUsername=代理用户名(可选) -Dreactor.netty.http.client.proxyPassword=代理密码(可选)
该方案配置成本最低,适合统一出口代理的场景。方案3:容器层面配置透明代理
部署在Rancher、AWS ECS等容器环境时,可以直接给网关容器配置全局HTTP/HTTPS代理环境变量,搭配方案2的JVM参数即可无需修改应用代码:
HTTP_PROXY=http://代理地址:端口 HTTPS_PROXY=http://代理地址:端口 NO_PROXY=localhost,127.0.0.1,集群内部服务域名后缀
内容的提问来源于stack exchange,提问作者C Learly

