psytester
psytester

Reputation: 244

spring-boot app as spring-cloud-gateway has to use a proxy: JVM arguments not used NOR spring.cloud.gateway.httpclient.proxy.****

Should spring-boot be able to use a proxy by global JVM arguments?

For testing purpose, I want to modify the response between two applications with ZAP Proxy.

In frontend application, I have setup the java process with global JVM arguments for proxy usage:

java -Dhttps.proxyHost=10.1.93.90 \
     -Dhttps.proxyPort=3128 \
     -Dhttp.proxyHost=10.1.93.90 \
     -Dhttp.proxyPort=3128 \
     -jar myapplication.jar

But the proxy is not used. Only one request goes via proxy at application startup to openID provider to fetch the /auth/realms/master/.well-known/openid-configuration

I know how to setup a proxy JVM-wide and it works for non spring-boot applications.

I read different articles, e.g. so #33951240 or spring-boot issue #3968 etc... BUT in that case I can not add any additional code, since I have to use it as it is, so spring devtools is no option nor any advice to add some code. I could ask my dev team, to add something, but only as a last option.

Code snippet where the request is routed to backend application:

import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
[.....]

    protected Mono<ServerWebExchange> prepareExchange(ServerWebExchange exchange, ServerHttpRequest request) {
        return Mono.just(exchange.mutate().request(request).build());
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {

        return ServerWebExchangeUtils.cacheRequestBody(exchange, request -> {

            return prepareExchange(exchange, request) //
                    .flatMap(mappedExchange -> chain.filter(mappedExchange).thenReturn(mappedExchange)) //
                    .flatMap(mappedExchange -> setRedirect(mappedExchange).thenReturn(mappedExchange)) //
                    .then()
                    .onErrorResume(OAuth2AuthorizationException.class, e -> setRedirectAfterError(exchange));//
        });
    }
[......]
  1. EDIT after feedback of my DEV team. Important info is, that this applications acts as a gateway between frontend (browser) and a backend. The application.yml contains gateway settings to route the traffic according to spring-cloud-gateway

According to spring-cloud-gateway issues #176 this is possible since 2.0.0.M8.

We are using spring-boot 2.2.4 with spring-cloud-gateway 2.2.1 and reactor-netty 0.9.4

So I should be able to use this setup?

spring.cloud.gateway.httpclient.proxy.host=10.1.93.90
spring.cloud.gateway.httpclient.proxy.port=3128

But with such settings, the route configuration in gateway is ignored completly and the frontend (browser) tries to connect the backend directly. Strange!

Upvotes: 0

Views: 1948

Answers (1)

psytester
psytester

Reputation: 244

ARGHH! This was finally an additional issue of ZAP proxy.

After enabling of debugging output I saw some strange HTTP headers and the 302 Redirect, why the browser is trying to connect the backend directly.

Received response (auto-read:false) : [.....
    Content-Security-Policy=.....connect-src https://zap wss://zap;.....
    Access-Control-Allow-Headers=ZAP-Header,
    X-Clacks-Overhead=GNU Terry Pratchett,
    Location=https://<backend-ip>/.....] - r.n.h.c.HttpClientOperations:254

With such header infos I searched and found the final root cause of my problem in zaproxy issues #5790.

To summarize the resolution.

  1. spring-cloud-gateway needs special config
spring.cloud.gateway.httpclient.proxy.host=<ip of proxy>
spring.cloud.gateway.httpclient.proxy.port=<port of proxy>
  1. if ZAP Proxy is used: After disabling the HUD Feature in ZAP proxy, it works as expected.

Upvotes: 1

Related Questions