OkHTTPClient Проверка подлинности прокси-сервера, как?

Вопрос: как добавить прокси авторизации в OkHTTP.

Я знаю, что конструктор OkHTTP поддерживает прокси, хотя мне трудно настроить один вверх.

/**
 * Given a Url and a base64 encoded password return the contents of a website.
 * @param urlString
 * @param password
 * @return JSON
 */
public String getURLJson(String urlString, String password) {       
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .build();

        Request request = new Request.Builder()
          .url(urlString)
          .get()
          .addHeader("authorization", "Basic " + password)
          .addHeader("cache-control", "no-cache")
          .build();

        Response response = null;
        try {
            response = client.newCall(request).execute();
            String string = response.body().string();
            response.body().close();
            return string;
        } catch (IOException e) {
            System.err.println("Failed scraping");
            e.printStackTrace();
        }
        return "failed";
    }

У меня есть IP/порт/имя пользователя/пароль.

Хотя я не знаю, как превратить их в Proxy proxy, который затем можно использовать в client.SetProxy().

Это кажется слишком сложным, и я просто не могу понять это. Любая помощь будет оценена по достоинству.


person Liably    schedule 22.02.2016    source источник


Ответы (1)


Попробуй это:

int proxyPort = 8080;
String proxyHost = "proxyHost";
final String username = "username";
final String password = "password";

Authenticator proxyAuthenticator = new Authenticator() {
  @Override public Request authenticate(Route route, Response response) throws IOException {
       String credential = Credentials.basic(username, password);
       return response.request().newBuilder()
           .header("Proxy-Authorization", credential)
           .build();
  }
};

OkHttpClient client = new OkHttpClient.Builder()
    .connectTimeout(60, TimeUnit.SECONDS)
    .writeTimeout(60, TimeUnit.SECONDS)
    .readTimeout(60, TimeUnit.SECONDS)
    .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)))
    .proxyAuthenticator(proxyAuthenticator)
    .build();
person Jesse Wilson    schedule 23.02.2016
comment
Похоже, прокси не аутентифицируется. Мне удалось заставить его работать с командной строкой curl -x user:passS@proxy:port address с этими данными, хотя у вас, похоже, нет аутентификации. Я получаю сообщение об ошибке Access Denied (authentication_failed) - person Liably; 23.02.2016
comment
Какой код ответа HTTP? С прокси-аутентификатором OkHttp должен повторить попытку повторной аутентификации прокси-сервера, прежде чем сообщать об этой ошибке вызывающей стороне. - person Jesse Wilson; 24.02.2016
comment
У меня тоже не работает. Я всегда получаю ответ 407 Proxy Authentication Required. И завитки работают. - person Robinho; 06.08.2017
comment
К вашему сведению, код выдает java.lang.RuntimeException: java.net.ProtocolException: Too many follow-up requests: 21, когда имя пользователя и пароль неверны. Проверено и проверено, работает. См. https://github.com/http-builder-ng/http-builder-ng/issues/191 для моего фрагмента кода. - person Raviteja; 12.03.2018
comment
@JesseWilson Решение с Authenticator у меня работает (с использованием okhttp 4.3.0). Спасибо. Но когда я добавляю заголовок Proxy-Authorization вручную через Request.Builder, он не работает. Я дважды проверил с помощью curl правильность используемого заголовка. Делает ли okhttp какую-то внутреннюю магию, которая не очевидна? Это не проблема, но было бы интересно узнать. - person rapstacke; 28.05.2020
comment
Когда вы добавляете его в Request.Builder, эти данные отправляются на веб-сервер, а не на прокси-сервер. Здесь есть два разных запроса; один для прокси и другой для веб-сервера. - person Jesse Wilson; 29.05.2020