spring-cloud / spring-cloud-gateway

An API Gateway built on Spring Framework and Spring Boot providing routing and more.
http://cloud.spring.io
Apache License 2.0
4.52k stars 3.32k forks source link

Proxy Support in gateway #176

Closed pravinkumarb84 closed 6 years ago

pravinkumarb84 commented 6 years ago

I am trying to enable proxy for gateway as below.

I have provide the below jvm args in the gateway application startup. jvmArgs "-Dhttp.proxyHost=http://proxy.ourcompanyname.com", "-Dhttp.proxyPort=8080", "-Dhttps.proxyHost=http://proxy.ourcompanyname.com", "-Dhttp.proxyPort=8080", "-Dhttp.nonProxyHosts=localhost|*.ourcompanyname.com"

it is not working. Similar issue has been addressed in zuul as part of the issue https://github.com/spring-cloud/spring-cloud-netflix/issues/1791

Please advice how to enable proxyHost for gateway application.?

spencergibb commented 6 years ago

I don't know if the Reactor Netty HttpClient supports that. @smaldini?

smaldini commented 6 years ago

We do support proxying but that would need a programmatic configuration on the side of the gateway tho @spencergibb - you can use the ClientOption#proxy (see https://github.com/cloudfoundry/cf-java-client/blob/master/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/_ProxyConfiguration.java#L32) to configure a proxy builder like this https://github.com/reactor/reactor-netty/blob/master/src/test/java/reactor/ipc/netty/options/ClientProxyOptionsTests.java

spencergibb commented 6 years ago

Thanks @smaldini

pravinkumarb84 commented 6 years ago

@spencergibb any time lines for this enhancement?

spencergibb commented 6 years ago

No, but you just need to create a HttpClient bean and configure it properly.

dalegaspi commented 4 years ago

looking at the code today this can be done by adding this in the application.yml

spring:
  cloud:
    gateway:
      httpclient:
        proxy:
          host: localhost
          port: 8888

i tried this today and it worked.

ashokkumar7505 commented 4 years ago

@dalegaspi Hi, Is there any way to get this done programmatically rather than providing corresponding parameters in application.yml as you did.

dalegaspi commented 4 years ago

@dalegaspi Hi, Is there any way to get this done programmatically rather than providing corresponding parameters in application.yml as you did.

per @spencergibb you can create an HttpClient bean but i haven’t tried that.

escholer-pyx commented 4 years ago

I am trying to configure Spring Cloud Gateway to validate JWT access tokens using Spring Security. Unfortunately, I have to go through an authenticated proxy server in my dev environment.

I am setting the http.proxy and https.proxy environment variables, which was necessary to get the request to the auth server's https://login.microsoftonline.com/{tenantId}/v2.0/.well-known/oidc-configuration endpoint to work. The proxy settings do not appear to be used though when fetching the JWKS file from the URL given in the OIDC config (https://login.microsoftonline.com/{tenantId}/discovery/v2.0/keys).

Is there a separate proxy config that is needed to fetch the JWT key set?

I also have the spring.cloud.gateway.httpclient.proxy.* properties set in my application.properties.

Any help is greatly appreciated. Thank you.

yoghurt1131 commented 4 years ago

@escholer-pyx

I had a same problem. In spring-cloud-gateway-mvc, I did it by implementing ClientHttpRequestFactory that using extended HttpClientBuilder.

HeaderCustomizeHttpClientBuilder.java

public class HeaderCustomizeHttpClientBuilder extends HttpClientBuilder {

    @Override
    protected ClientExecChain createMainExec(HttpRequestExecutor requestExec, HttpClientConnectionManager connManager,
                                             ConnectionReuseStrategy reuseStrategy, ConnectionKeepAliveStrategy keepAliveStrategy,
                                             HttpProcessor proxyHttpProcessor,
                                             AuthenticationStrategy targetAuthStrategy,
                                             AuthenticationStrategy proxyAuthStrategy,
                                             UserTokenHandler userTokenHandler) {
        HttpProcessor headerCustomizeHttpProcessor = new ImmutableHttpProcessor(
                new RequestTargetHost(),
                //
                // add auth header for proxy connect
                //
                (request, context) -> request.addHeader("Name", "Value")
        );

        return super.createMainExec(requestExec, connManager, reuseStrategy,
                keepAliveStrategy, headerCustomizeHttpProcessor,
                targetAuthStrategy, proxyAuthStrategy, userTokenHandler);
    }
}

ClientHttpRequestFactoryBuilder.java

public class ProxyClientHttpRequestFactoryBuilder implements ClientHttpRequestFactoryBuilder {

    @Override
    public ClientHttpRequestFactory build() {
        HttpClientBuilder httpClientBuilder = HeaderCustomizeHttpClientBuilder.create();
       //
       // set your proxy domain and port.
       //
        httpClientBuilder.setProxy(new HttpHost("proxydomain", proxyport));
        return new HttpComponentsClientHttpRequestFactory(httpClientBuilder.build());
    }
}
wunaidage commented 4 years ago

@dalegaspi Hi, Is there any way to get this done programmatically rather than providing corresponding parameters in application.yml as you did.

I believe you can load different configuration by profiling

gsartori commented 2 weeks ago

Hi folks, I need to configure the gateway to connect to a NON STANDARD proxy and authenticate programmatically with oAuth2. This is of course not feasable with just the proxy configuration.

Is there a way to develop a bean that overrides the default behaviour an that will be used each time an HTTP connection is made by the gateway?

How can I implement a custom Proxy code? Thank you for any hint or word of wisdom

spencergibb commented 2 weeks ago

@gsartori create a HttpClientCustomizer bean and use the proxy api https://projectreactor.io/docs/netty/release/reference/index.html#_proxy_support_2

gsartori commented 2 weeks ago

@spencergibb thank you for your reply. I did as you suggested. The SAP API I'm using lets me get an HttpClient already configured with all the proxy things done for me, the problem I have now is that I get an org.apache.hc.client5.http.classic.HttpClient instead of an reactor.netty.http.client.HttpClient.

I can live with the Tomcat version of the Spring Gateway, but it seems that version does not support the HttpClientCustomizer API. Are you planning on porting that to the Tomcat MVC version?

Thank you for your time, I appreciate it, Gianluca

spencergibb commented 2 weeks ago

I can't add a customizer since there can be multiple clients in the webmvc gateway. In your case, you'll need to create a HttpComponentsClientHttpRequestFactory bean and pass in the apache HttpClient as a constructor parameter.

gsartori commented 2 weeks ago

Just to make sure I got it right, does the following code do the trick?

@Configuration
class MyHttpClientConfiguration {

    @Bean
    HttpComponentsClientHttpRequestFactory requestFactory() {
        // Replace the following with a custom HttpClient instance
        return new HttpComponentsClientHttpRequestFactory(httpClient())
    }

}

Do I have to do something else to make it work?

spencergibb commented 2 weeks ago

Seems ok

gsartori commented 2 weeks ago

It worked, thank you wevy much. (Of course..) I now have the requirement of using different HttpClients for for different routes. Any idea on how to address this?

spencergibb commented 2 weeks ago

It is not currently possible

gsartori commented 2 weeks ago

Thank you @spencergibb, just out of curiosity, do you have any plan on implementing such a feature? Anybody else asking for it?

spencergibb commented 2 weeks ago

no to both