Posted at

Feignに認証ありのProxyを設定する方法

More than 1 year has passed since last update.


FeignのProxy対応(認証あり)

インターネットに接続する際、認証が必要なproxyを経由しなければならない会社等もあるかと思います。

そのような環境でAPIクライアントであるFeignを利用して、インターネット上に公開されているAPIを呼び出す際のproxyの設定方法について説明したいと思います。

FeignはHTTPリクエストを発行する処理を別のライブラリにデリゲートしています。

つまり、利用するライブラリのproxy対応を行えばよいということです。

今回はFeignGitHubページで説明されているGitHubの指定したリポジトリのコントリビュータを取得するサンプルproxy対応に変更してみます。

なお、Feignの説明ついては「インターフェースだけでAPIクライアントを実装するFeignがすごく便利!」に書いていますのでそちらを参照ください。


GitHubDemo.java

package com.example.feign.demo.github;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.List;
import java.util.concurrent.TimeUnit;

import feign.Feign;
import feign.jackson.JacksonDecoder;
import okhttp3.Authenticator;
import okhttp3.Credentials;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;

/**
* modify Feign example(https://github.com/OpenFeign/feign) to corresponded proxy
*/

public class GitHubDemo {

public static void main(String[] args) {

// create instance of okhttp3.OkHttpClient corresponded proxy
OkHttpClient client = createOkHttpClientCorrespondedProxy("127.0.0.1",
8080, "userId", "pass");

// feign use proxy with authentication
GitHub github = Feign.builder()
// set instance of feign.Client.OkHttpClient
.client(new feign.okhttp.OkHttpClient(client))
// use Jackson
.decoder(new JacksonDecoder())
.target(GitHub.class, "https://api.github.com");

// call api [GET /repos/{owner}/{repo}/contributors]
List<Contributor> contributors = github.contributors("OpenFeign",
"feign");
for (Contributor contributor : contributors) {
System.out.println(
contributor.login + " (" + contributor.contributions + ")");
}
}

/**
* create instance of okhttp3.OkHttpClient corresponded proxy
* @param proxyHost proxy's host url or ipAddress
* @param proxyPort proxy's port number
* @param userId userId of proxy's authentication
* @param pass pass of proxy's authentication
* @return instance of okhttp3.OkHttpClient
*/

private static OkHttpClient createOkHttpClientCorrespondedProxy(
String proxyHost, int proxyPort, String userId, String pass) {

// okhttp3.Authenticator : correct
// java.net.Authenticator : incorrect
Authenticator proxyAuthenticator = new Authenticator() {
@Override
public Request authenticate(Route route,
Response response) throws IOException {
String credential = Credentials.basic(userId, pass);
return response.request().newBuilder()
.header("Proxy-Authorization", credential).build();
}
};

// okhttp3.OkHttpClient : correct
// feign.Client.OkHttpClient : incorrect
return new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.proxy(new Proxy(Proxy.Type.HTTP,
new InetSocketAddress(proxyHost, proxyPort)))
.proxyAuthenticator(proxyAuthenticator).build();
}
}


注意すべきポイントを以下に示します。



  • feign.okhttp.OkHttpClientのインスタンスを生成する際、okhttp3.OkHttpClientを引数にとるコンストラクタを利用する


  • okhttp3.OkHttpClientのインスタンスを生成する際、proxyに対応するようにコンフィグレーションする

  • 同じクラス名のものがあるのでimportする際は注意すること



    • okhttp3.Authenticatorが正しく、java.net.Authenticatorは誤り


    • okhttp3.OkHttpClientが正しく、feign.Client.OkHttpClientは誤り(proxy対応のokhttpのインスタンスを生成する)



(参考)

https://stackoverflow.com/questions/35554380/okhttpclient-proxy-authentication-how-to