概要
jsoupを使ってプロキシ経由でアクセスする必要があったのですが、思いのほか手こずりました。
ポイントは以下の二点です。
- 認証が必要なプロキシ経由でHTTPSアクセスをできないように、デフォルトで設定されている(Java 8から)。
-
Authenticator.setDefault()
で、プロキシサーバーのユーザーIDとパスワードを指定する必要がある。
環境
jsoup
pom.xml
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.1</version>
</dependency>
Javaバージョン: 8
OK例
// 「認証が必要なプロキシ経由でのHTTPSアクセスを禁止」という設定を解除します。
// デフォルトではこのプロパティに"Basic"が指定されており、Basic認証が利用できないようになっていますので、"Basic"の設定を解除するため、空文字で上書きします。
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
// プロキシサーバーのID/パスワードをAuthenticator経由で渡すようにします。
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("{プロキシサーバーのユーザーID}", "{プロキシサーバーのパスワード}".toCharArray());
}
});
Jsoup.connect("{アクセスしたいURL}")
.proxy("{プロキシサーバーのID or ホスト名}", {プロキシサーバーのポート番号})
.get();
NG例
// Authorizationヘッダーを使うバージョン その1
Jsoup.connect("{アクセスしたいURL}")
.header("Authorization", "Basic " + Base64.getEncoder().encodeToString("{プロキシサーバーのユーザーID}:{プロキシサーバーのパスワード}".getBytes()))
.proxy("{プロキシサーバーのIPアドレス or ホスト名}", {プロキシサーバーのポート番号})
.get();
// Authorizationヘッダーを使うバージョン その2 (ヘッダーの値に"Basic "の文字列を指定しない)
Jsoup.connect("{アクセスしたいURL}")
.header("Authorization", Base64.getEncoder().encodeToString("{プロキシサーバーのユーザーID}:{プロキシサーバーのパスワード}".getBytes()))
.proxy("{プロキシサーバーのIPアドレス or ホスト名}", {プロキシサーバーのポート番号})
.get();
// Proxy-Authorizationヘッダーを使うバージョン その1
Jsoup.connect("{アクセスしたいURL}")
.header("Proxy-Authorization", "Basic " + Base64.getEncoder().encodeToString("{プロキシサーバーのユーザーID}:{プロキシサーバーのパスワード}".getBytes()))
.proxy("{プロキシサーバーのIPアドレス or ホスト名}", {プロキシサーバーのポート番号})
.get();
// Proxy-Authorizationヘッダーを使うバージョン その2 (ヘッダーの値に"Basic "の文字列を指定しない)
Jsoup.connect("{アクセスしたいURL}")
.header("Proxy-Authorization", Base64.getEncoder().encodeToString("{プロキシサーバーのユーザーID}:{プロキシサーバーのパスワード}".getBytes()))
.proxy("{プロキシサーバーのIPアドレス or ホスト名}", {プロキシサーバーのポート番号})
.get();
// 「jdk.http.auth.tunneling.disabledSchemes」の指定なし
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("{プロキシサーバーのユーザーID}", "{プロキシサーバーのパスワード}".toCharArray());
}
});
Jsoup.connect("{アクセスしたいURL}")
.proxy("{プロキシサーバーのID or ホスト名}", {プロキシサーバーのポート番号})
.get();
いずれの場合も、以下のとおりエラーとなりました。
java.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.1 407 Proxy Authentication Required"
参考(謝辞)
大変参考になりました!ありがとうございます!
https://qiita.com/kaakaa_hoe/items/d4fb11a3af035a287972