FeignのProxy対応(認証あり)
インターネットに接続する際、認証が必要なproxy
を経由しなければならない会社等もあるかと思います。
そのような環境でAPIクライアントであるFeign
を利用して、インターネット上に公開されているAPIを呼び出す際のproxy
の設定方法について説明したいと思います。
Feign
はHTTPリクエストを発行する処理を別のライブラリにデリゲートしています。
つまり、利用するライブラリのproxy
対応を行えばよいということです。
今回はFeign
のGitHubページで説明されている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