Описание
Я пытаюсь подключиться к веб-серверу, который использует https, через прокси-сервер, который требует аутентификацию, но он не работает.
Класс HttpsURLConnection отправляет первый запрос на открытие туннеля без заголовка «Proxy-Authorization», даже если принудительно.
В этом случае сервер вернет «407 Proxy Authentication Required».
Код для воспроизведения проблемы
public class TestProxy {
@Test
public void testOne() throws IOException {
final String PROXY_USERNAME = "username";
final String PROXY_PASSWORD = "password";
final String PROXY_HOSTNAME = "hostname";
final int PROXY_PORT = 8080;
Authenticator.setDefault(
new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(PROXY_USERNAME, PROXY_PASSWORD.toCharArray());
}
});
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOSTNAME, PROXY_PORT));
URL url = new URL("https://www.google.com");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(proxy);
assertNotEquals(407, connection.getResponseCode());
}
@Test
public void testTwo() throws IOException {
final String PROXY_USERNAME = "username";
final String PROXY_PASSWORD = "password";
final String PROXY_HOSTNAME = "hostname";
final int PROXY_PORT = 8080;
Authenticator.setDefault(
new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(PROXY_USERNAME, PROXY_PASSWORD.toCharArray());
}
});
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOSTNAME, PROXY_PORT));
URL url = new URL("https://www.google.com");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(proxy);
String userCredentials = PROXY_USERNAME + ":" + PROXY_PASSWORD;
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes()));
connection.setRequestProperty("Proxy-Authorization", basicAuth);
assertNotEquals(407, connection.getResponseCode());
}
}
Запрос отправлен
CONNECT www.google.com:443 HTTP/1.1
User-Agent: Java/1.8.0_162
Host: www.google.com
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Proxy-Connection: keep-alive
Возможная причина
Я думаю, что это поведение вызвано методом sun.net.www.protocol.http.HttpURLConnection.sendCONNECTRequest()
Создает новый «запрос на подключение» без добавления заголовка «Proxy-Authorization».
Обход
Обходное решение - сначала подключиться к http-адресу, чтобы прокси-сервер зарегистрировал пользовательский агент и авторизовал подключение без добавления заголовка Proxy-Authorization
Версия jdk: 1.8.0_181-b13.