3

I want to consume a REST service from the outside world behind a corporate proxy with authentication.

How do I configure Spring Boot + Spring Cloud Feign/Ribbon to use our proxy?

g00glen00b
  • 41,995
  • 13
  • 95
  • 133
Guido Zockoll
  • 141
  • 3
  • 11

3 Answers3

8

I believe you're looking for something like this:

import feign.Feign;
import okhttp3.OkHttpClient;
import java.net.InetSocketAddress;
import java.net.Proxy;
...
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy-url", 1234));
OkHttpClient okHttpClient = new OkHttpClient.Builder().proxy(proxy).build();
Feign.builder()
    .client(new feign.okhttp.OkHttpClient(okHttpClient))
    .target(...);

You just have to additionally add compile 'io.github.openfeign:feign-okhttp:9.5.0' to your project.

The target clause contains your defined Interface. Further reference: https://github.com/OpenFeign/feign

user3105453
  • 1,881
  • 5
  • 32
  • 55
1

Turns out there is actually a much easier solution.

The following information will be helpful (also for more advanced use cases):

OpenFeign Client can run with several HTTP Clients. By default it uses java.net.URLConnection, but you can also use ApacheHttpClient or OkHttpClient.

Using Apache Http Client

Here is what you can do to set a proxy using ApacheHttpClient:

  1. Add the following two dependencies to your pom.xml:
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- Dependency to switch HttpClient implementation from java.net.URLConnection to Apache HTTP Client -->
<!-- See also: FeignAutoConfiguration for details. -->
<!-- See also: https://cloud.spring.io/spring-cloud-commons/reference/html/#http-clients -->
<!-- See also: https://cloud.spring.io/spring-cloud-openfeign/reference/html/#spring-cloud-feign-overriding-defaults -->
<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-httpclient</artifactId>
</dependency>

In your app expose the following bean:

// see: https://cloud.spring.io/spring-cloud-commons/reference/html/#http-clients
@Bean
public HttpClientBuilder proxiedHttpClient() {
  String proxyHost   = "client-envoy";
  Integer proxyPort  = 80
  String proxyScheme = "http";

  return HttpClientBuilder.create()
                          .setProxy(new HttpHost(proxyHost, proxyPort, proxyScheme));
}

That's it - nothing else needs to be configured in application.yaml since ApacheHttpClient will be used by default, if it is on the classpath.

Using Ok Http Client

To set a proxy using OkHttpClient you do a similar thing:

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-okhttp</artifactId>
</dependency>

In your application.yml make sure to enable OkHttpClient and disable ApacheHttpClient:

spring:
 cloud:
   httpclientfactories:
     ok:
       enabled: true
     apache:
       enabled: false

feign:
 okhttp:
   enabled: true
 httpclient:
   enabled: false

Instead of HttpClientBuilder expose a bean of type OkHttpClient.Builder.

FloW
  • 139
  • 10
0

Spring cloud feign supports three underlying implementations:

  1. Default
  2. Apache HttpClient
  3. OkHttpClient

If using Default:

Create this spring bean (say by defining inside class with @Configuration annotation), no changes required in application properties/yml:

  @Bean
  public Client feignClient() {
    return new Client.Proxied(
        null, null, new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)));
  }

If using Apache HttpClient:

that means you have feign.httpclient.enabled: true in application.yml and below in your pom.xml or build.gradle:

pom.xml
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

build.gradle
implementation 'io.github.openfeign:feign-httpclient'

Create this spring bean (say by defining inside class with @Configuration annotation):

  @Bean
  public CloseableHttpClient feignClient() {
    return HttpClientBuilder.create().setProxy(new HttpHost(proxyHost, proxyPort)).build();
  }

If using OkHttpClient:

that means you have feign.okhttp.enabled: true in application.yml and below in your pom.xml or build.gradle:

pom.xml
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-okhttp</artifactId>
</dependency>

build.gradle
implementation 'io.github.openfeign:feign-okhttp'

Create this spring bean (say by defining inside class with @Configuration annotation):

  @Bean
  public OkHttpClient feignClient() {
    return new OkHttpClient.Builder()
        .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)))
        .build();
  }
Amith Kumar
  • 4,400
  • 1
  • 21
  • 28