Skip to content

feat: honour JVM proxy system properties in reactive OAuth2 client#100

Merged
chrisbonilla95 merged 1 commit into
masterfrom
cbon/oidc-proxy-system-properties
May 25, 2026
Merged

feat: honour JVM proxy system properties in reactive OAuth2 client#100
chrisbonilla95 merged 1 commit into
masterfrom
cbon/oidc-proxy-system-properties

Conversation

@chrisbonilla95
Copy link
Copy Markdown
Contributor

Summary

The customWebClient used by Spring Security's reactive OAuth2 client for token exchange, userinfo, and refresh-token calls is built on Reactor Netty's HttpClient, which does not consult JVM proxy system properties by default. The JDK-based RestTemplate paths in this same library do consult them (ClientRegistrations.fromIssuerLocation for OIDC discovery, SimpleRemoteJwkSource for JWKS), creating a partial-proxy behaviour where OIDC discovery and JWKS calls go through a corporate proxy but token/userinfo/refresh calls silently bypass it.

Symptom for a customer behind a corporate egress proxy: the browser-side redirect to the IdP completes and credentials work, but the server-side callback (token exchange) hangs or 502s because the auth-service pod cannot reach the IdP's token endpoint directly.

Adding .proxyWithSystemProperties() to the HttpClient chain closes the gap. The call is a no-op when no proxy system properties are set, so customers who do not configure a proxy see no behaviour change.

What changed

  • gooddata-server-oauth2-autoconfigure/src/main/kotlin/ReactiveCommunicationClientsConfiguration.kt:62-66 — one chained call on the HttpClient builder, plus a comment explaining the rationale.
  • gooddata-server-oauth2-autoconfigure/src/test/kotlin/ReactiveCommunicationClientsConfigurationTest.kt — new unit test asserting both states (no proxy props ⇒ hasProxy() is false; https.proxyHost/https.proxyPort set ⇒ supplier-backed HTTP ProxyProvider matches host/port).

Test plan

  • ./gradlew :gooddata-server-oauth2-autoconfigure:test — 261 tests pass (2 new, 259 pre-existing)
  • ./gradlew :gooddata-server-oauth2-autoconfigure:detekt :gooddata-server-oauth2-autoconfigure:detektTest — clean
  • Verified end-to-end against a real IdP behind a corporate proxy (cannot reproduce locally; recommend a consumer (gdc-nas auth-service) deploy and smoke-test login flow)

Notes on proxyProviderSupplier vs proxyProvider

Reactor Netty 1.2.x stores system-property-derived proxies as a Supplier<ProxyProvider> (lazy) on ClientTransportConfig, separate from the eager ProxyProvider field. hasProxy() is the right boolean check, since proxyProvider() alone returns null even when a supplier-backed proxy is configured. The test asserts against both to make this explicit.

Risk

risk: low — additive call that is a no-op for customers who do not set JVM proxy system properties. Behaviour for OIDC-only customers without a proxy is unchanged.

JIRA: TRIVIAL

The `customWebClient` used for OIDC token exchange, userinfo, and refresh-token calls is built on Reactor Netty's `HttpClient`, which does not consult JVM system properties for proxy configuration by default. Customers behind a corporate egress proxy who set the standard `-Dhttps.proxyHost`/`-Dhttp.proxyHost`/`-Dhttp.nonProxyHosts` JVM args (or `HTTPS_PROXY` env vars picked up by their JVM) see those settings honoured by the JDK-based `RestTemplate` paths in this library (OIDC discovery via `ClientRegistrations.fromIssuerLocation`, JWKS fetch via `SimpleRemoteJwkSource`) but silently bypassed by every Reactor Netty call. The result is that login completes the browser-side redirect but hangs on the server-side token exchange callback.

Adding `.proxyWithSystemProperties()` to the `HttpClient` builder closes that gap and makes the reactive OAuth2 client consistent with the JDK paths already present in this configuration. The call is a no-op when no proxy properties are set, so customers who do not need a proxy see no behaviour change.

Added unit coverage that verifies both behaviours (no proxy props → `hasProxy()` is false; `https.proxyHost`/`https.proxyPort` set → supplier-backed HTTP `ProxyProvider` matches host/port).

JIRA: TRIVIAL
risk: low
Copy link
Copy Markdown
Contributor

@jeskepetr jeskepetr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.
Thanks for the fix

@chrisbonilla95 chrisbonilla95 merged commit e1997d2 into master May 25, 2026
2 checks passed
@chrisbonilla95 chrisbonilla95 deleted the cbon/oidc-proxy-system-properties branch May 25, 2026 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants