Заголовок Proxy-Authorization удален при использовании https

Я пытаюсь получить доступ к URL-адресу https через прокси-сервер, который требует аутентификации в java, и заголовок Proxy-Authorization не передается прокси-серверу.

Я знаю, что сетевой аспект работает, потому что я могу выполнить именно то, что мне нужно, используя curl:

$ curl -H "Прокси-авторизация: базовая ##########" -x my_proxy_host:80 my_https_url -v

Мой код, кажется, работает, когда я обращаюсь к URL-адресу http, однако, когда я пытаюсь получить доступ к URL-адресу https, я получаю 403 Forbidden и вижу в журналах, что заголовок Proxy-Authorization не передается с Java на прокси.

Вот мой код:

public static void main(String args[]) {
    try {

        HttpHost proxy = new HttpHost(my_proxy_host, 80, "http");

        DefaultHttpClient cli = new DefaultHttpClient();

        cli.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

        HttpHost target = new HttpHost(my_https_endpoint, 443, "https");

        HttpGet get = new HttpGet("/");

        get.setHeader("Proxy-Authorization", "Basic ##############");

        HttpResponse response = cli.execute(target, get);

        HttpEntity entity = response.getEntity();

        System.out.println("----------------------------------------");
        System.out.println(response.getStatusLine());
        if (entity != null) {
            System.out.println("Response content length: " + entity.getContentLength());
        }

        EntityUtils.consume(entity);                        
    } catch (Exception e) {
        e.printStackTrace();
    }
} 

Обратите внимание, что если вы измените следующую строку, приведенный выше код будет работать:

Цель HttpHost = новый HttpHost (my_https_endpoint, 80, "http");

Любые идеи очень приветствуются.

Спасибо!


Вот журналы, которые создает apache httpclient.

Вот версия, которая не работает, пытаясь получить доступ к конечной точке https через порт 443.

09:43:43.574 [main] DEBUG o.a.h.i.conn.SingleClientConnManager - Get connection for route HttpRoute[{tls}->my_proxy_host:80->my_https_endpoint:443]
09:43:43.653 [main] DEBUG o.a.h.i.c.DefaultClientConnectionOperator - Connecting to my_proxy_host:80
09:43:43.716 [main] DEBUG o.a.h.c.protocol.RequestAuthCache - Auth cache not set in the context
09:43:43.716 [main] DEBUG o.a.h.i.conn.DefaultClientConnection - Sending request: CONNECT my_https_endpoint:443 HTTP/1.1
09:43:43.717 [main] DEBUG org.apache.http.wire - >> "CONNECT my_https_endpoint:443 HTTP/1.1[\r][\n]"
09:43:43.720 [main] DEBUG org.apache.http.wire - >> "Host: my_https_endpoint:443[\r][\n]"
09:43:43.721 [main] DEBUG org.apache.http.wire - >> "Proxy-Connection: Keep-Alive[\r][\n]"
09:43:43.721 [main] DEBUG org.apache.http.wire - >> "User-Agent: Apache-HttpClient/4.1.2 (java 1.5)[\r][\n]"
09:43:43.721 [main] DEBUG org.apache.http.wire - >> "[\r][\n]"
09:43:43.721 [main] DEBUG org.apache.http.headers - >> CONNECT my_https_endpoint:443 HTTP/1.1
09:43:43.721 [main] DEBUG org.apache.http.headers - >> Host: my_https_endpoint:443
09:43:43.721 [main] DEBUG org.apache.http.headers - >> Proxy-Connection: Keep-Alive
09:43:43.721 [main] DEBUG org.apache.http.headers - >> User-Agent: Apache-HttpClient/4.1.2 (java 1.5)
09:43:43.762 [main] DEBUG org.apache.http.wire - << "HTTP/1.1 403 Forbidden[\r][\n]"
09:43:43.766 [main] DEBUG o.a.h.i.conn.DefaultClientConnection - Receiving response: HTTP/1.1 403 Forbidden
09:43:43.766 [main] DEBUG org.apache.http.headers - << HTTP/1.1 403 Forbidden
09:43:43.768 [main] DEBUG o.a.h.c.p.ResponseProcessCookies - Cookie spec not specified in HTTP context
09:43:43.772 [main] DEBUG o.a.h.i.conn.DefaultClientConnection - Connection closed
09:43:43.773 [main] DEBUG o.a.h.impl.client.DefaultHttpClient - CONNECT refused by proxy: HTTP/1.1 403 Forbidden
09:43:43.773 [main] DEBUG o.a.h.i.conn.SingleClientConnManager - Releasing connection org.apache.http.impl.conn.SingleClientConnManager$ConnAdapter@49869a03
HTTP/1.1 403 Forbidden
Response content length: 0

И вот версия, которая работает, доступ к конечной точке http через порт 80 (очевидно)

09:34:11.510 [main] DEBUG o.a.h.i.conn.SingleClientConnManager - Get connection for route HttpRoute[{}->my_proxy_host:80->my_http_endpoint:80]
09:34:11.646 [main] DEBUG o.a.h.i.c.DefaultClientConnectionOperator - Connecting to my_proxy_host:80
09:34:11.720 [main] DEBUG o.a.h.c.protocol.RequestAddCookies - CookieSpec selected: best-match
09:34:11.742 [main] DEBUG o.a.h.c.protocol.RequestAuthCache - Auth cache not set in the context
09:34:11.743 [main] DEBUG o.a.h.impl.client.DefaultHttpClient - Attempt 1 to execute request
09:34:11.743 [main] DEBUG o.a.h.i.conn.DefaultClientConnection - Sending request: GET my_http_endpoint:80/ HTTP/1.1
09:34:11.744 [main] DEBUG org.apache.http.wire - >> "GET my_http_endpoint:80/ HTTP/1.1[\r][\n]"
09:34:11.746 [main] DEBUG org.apache.http.wire - >> "Proxy-Authorization: Basic ###################[\r][\n]"
09:34:11.746 [main] DEBUG org.apache.http.wire - >> "Host: my_http_endpoint:80[\r][\n]"
09:34:11.747 [main] DEBUG org.apache.http.wire - >> "Proxy-Connection: Keep-Alive[\r][\n]"
09:34:11.747 [main] DEBUG org.apache.http.wire - >> "User-Agent: Apache-HttpClient/4.1.2 (java 1.5)[\r][\n]"
09:34:11.747 [main] DEBUG org.apache.http.wire - >> "[\r][\n]"
09:34:11.747 [main] DEBUG org.apache.http.headers - >> GET my_http_endpoint:80/ HTTP/1.1
09:34:11.747 [main] DEBUG org.apache.http.headers - >> Proxy-Authorization: Basic ###################
09:34:11.747 [main] DEBUG org.apache.http.headers - >> Host: my_http_endpoint:80
09:34:11.747 [main] DEBUG org.apache.http.headers - >> Proxy-Connection: Keep-Alive
09:34:11.747 [main] DEBUG org.apache.http.headers - >> User-Agent: Apache-HttpClient/4.1.2 (java 1.5)
09:34:11.880 [main] DEBUG org.apache.http.wire - << "HTTP/1.1 200 OK[\r][\n]"
09:34:11.889 [main] DEBUG org.apache.http.wire - << "Date: Fri, 29 Mar 2013 14:34:10 GMT[\r][\n]"
09:34:11.889 [main] DEBUG org.apache.http.wire - << "Expires: -1[\r][\n]"
09:34:11.889 [main] DEBUG org.apache.http.wire - << "Cache-Control: private, max-age=0[\r][\n]"
09:34:11.889 [main] DEBUG org.apache.http.wire - << "Content-Type: text/html; charset=ISO-8859-1[\r][\n]"
09:34:11.889 [main] DEBUG org.apache.http.wire - << "Set-Cookie: PREF=ID=918523062b63f55d:FF=0:TM=1364567650:LM=1364567650:S=T8IIsiH2_cw1UMLI; expires=Sun, 29-Mar-2015 14:34:10 GMT; path=/; domain=.google.com[\r][\n]"
09:34:11.890 [main] DEBUG org.apache.http.wire - << "Set-Cookie: NID=67=OHgx0xi1JDegF7uPjPUfW_pCC5Yn0H9S8-CMxyKbtgrF2vPQ-svFv1G4h5yxwCVEi2gDA23tywtEiYQvbPCHxDpAkefUlDJrWK94fEmXaiwuvua5w50eAej0yy3ysI4N; expires=Sat, 28-Sep-2013 14:34:10 GMT; path=/; domain=.google.com; HttpOnly[\r][\n]"
09:34:11.890 [main] DEBUG org.apache.http.wire - << "P3p: CP="This is not a P3P policy! See my_http_endpoint/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."[\r][\n]"
09:34:11.890 [main] DEBUG org.apache.http.wire - << "Server: gws[\r][\n]"
09:34:11.890 [main] DEBUG org.apache.http.wire - << "X-Xss-protection: 1; mode=block[\r][\n]"
09:34:11.890 [main] DEBUG org.apache.http.wire - << "X-Frame-options: SAMEORIGIN[\r][\n]"
09:34:11.890 [main] DEBUG org.apache.http.wire - << "Transfer-Encoding: chunked[\r][\n]"
09:34:11.890 [main] DEBUG org.apache.http.wire - << "Connection: close[\r][\n]"
09:34:11.891 [main] DEBUG org.apache.http.wire - << "[\r][\n]"
09:34:11.892 [main] DEBUG o.a.h.i.conn.DefaultClientConnection - Receiving response: HTTP/1.1 200 OK
09:34:11.892 [main] DEBUG org.apache.http.headers - << HTTP/1.1 200 OK
09:34:11.892 [main] DEBUG org.apache.http.headers - << Date: Fri, 29 Mar 2013 14:34:10 GMT
09:34:11.892 [main] DEBUG org.apache.http.headers - << Expires: -1
09:34:11.892 [main] DEBUG org.apache.http.headers - << Cache-Control: private, max-age=0
09:34:11.892 [main] DEBUG org.apache.http.headers - << Content-Type: text/html; charset=ISO-8859-1
09:34:11.892 [main] DEBUG org.apache.http.headers - << Set-Cookie: PREF=ID=918523062b63f55d:FF=0:TM=1364567650:LM=1364567650:S=T8IIsiH2_cw1UMLI; expires=Sun, 29-Mar-2015 14:34:10 GMT; path=/; domain=.google.com
09:34:11.892 [main] DEBUG org.apache.http.headers - << Set-Cookie: NID=67=OHgx0xi1JDegF7uPjPUfW_pCC5Yn0H9S8-CMxyKbtgrF2vPQ-svFv1G4h5yxwCVEi2gDA23tywtEiYQvbPCHxDpAkefUlDJrWK94fEmXaiwuvua5w50eAej0yy3ysI4N; expires=Sat, 28-Sep-2013 14:34:10 GMT; path=/; domain=.google.com; HttpOnly
09:34:11.892 [main] DEBUG org.apache.http.headers - << P3p: CP="This is not a P3P policy! See my_http_endpoint/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
09:34:11.892 [main] DEBUG org.apache.http.headers - << Server: gws
09:34:11.892 [main] DEBUG org.apache.http.headers - << X-Xss-protection: 1; mode=block
09:34:11.892 [main] DEBUG org.apache.http.headers - << X-Frame-options: SAMEORIGIN
09:34:11.892 [main] DEBUG org.apache.http.headers - << Transfer-Encoding: chunked
09:34:11.892 [main] DEBUG org.apache.http.headers - << Connection: close
09:34:11.916 [main] DEBUG o.a.h.c.p.ResponseProcessCookies - Cookie accepted: "[version: 0][name: PREF][value: ID=918523062b63f55d:FF=0:TM=1364567650:LM=1364567650:S=T8IIsiH2_cw1UMLI][domain: .google.com][path: /][expiry: Sun Mar 29 09:34:10 CDT 2015]"
09:34:11.917 [main] DEBUG o.a.h.c.p.ResponseProcessCookies - Cookie accepted: "[version: 0][name: NID][value: 67=OHgx0xi1JDegF7uPjPUfW_pCC5Yn0H9S8-CMxyKbtgrF2vPQ-svFv1G4h5yxwCVEi2gDA23tywtEiYQvbPCHxDpAkefUlDJrWK94fEmXaiwuvua5w50eAej0yy3ysI4N][domain: .google.com][path: /][expiry: Sat Sep 28 09:34:10 CDT 2013]". 
HTTP/1.1 200 OK
Response content length: -1
09:34:11.925 [main] DEBUG o.a.h.i.conn.SingleClientConnManager - Releasing connection org.apache.http.impl.conn.SingleClientConnManager$ConnAdapter@303459ed
09:34:11.925 [main] DEBUG o.a.h.i.conn.SingleClientConnManager - Released connection open but not reusable.
09:34:11.926 [main] DEBUG o.a.h.i.conn.DefaultClientConnection - Connection shut down

person user2209017    schedule 26.03.2013    source источник
comment
Почему вы не используете поставщика учетных данных, чтобы настроить это и позволить фреймворку сделать это?   -  person Dave G    schedule 26.03.2013
comment
Я не смог заставить фреймворк правильно аутентифицировать его, он успешно добавляет заголовок авторизации, но прокси-сервер, который я использую, ищет заголовок прокси-авторизации. У вас есть пример того, как это сделать?   -  person user2209017    schedule 26.03.2013
comment
Я могу осмотреться через несколько минут - следите   -  person Dave G    schedule 26.03.2013
comment
Спасибо за добавление журналов. Хорошо, похоже, что ваш прокси-сервер ОЖИДАЕТ, что заголовок аутентификации будет отправлен даже без запроса. HttpClient 4.x по умолчанию не выполняет упреждающую аутентификацию, но мы можем настроить его для этого — позвольте мне кое-что написать.   -  person Dave G    schedule 29.03.2013
comment
Кто-нибудь нашел решение с помощью аддона Heroku Proximo? Я сталкиваюсь с этой же проблемой.   -  person RC.    schedule 11.05.2013


Ответы (2)


Попробуйте этот вариант и посмотрите, может ли он удовлетворить ваши потребности:

public static void main(String args[]) {
    try {

        HttpHost proxy = new HttpHost(my_proxy_host, 80, "http");

        DefaultHttpClient cli = new DefaultHttpClient();

        cli.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
        cli.getCredentialsProvider().setCredentials(
            new AuthScope(proxy.getHostName(), proxy.getPort()),
            new UsernamePasswordCredentials("username", "password"));

        HttpHost target = new HttpHost(my_https_endpoint, 443, "https");

        HttpGet get = new HttpGet("/");

        // Example from: http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html#d5e1032
        BasicAuthCache authCache= new BasicAuthCache();
        // Target the proxy not target host
        authCache.put(proxy, new BasicScheme(ChallengeState.PROXY));
        BasicHttpContext context= new BasicHttpContext();
        context.setAttribute(ClientContext.AUTH_CACHE, authCache);
        HttpResponse response = cli.execute(target, get, context);

        HttpEntity entity = response.getEntity();

        System.out.println("----------------------------------------");
        System.out.println(response.getStatusLine());
        if (entity != null) {
            System.out.println("Response content length: " + entity.getContentLength());
        }

        EntityUtils.consume(entity);                        
    } catch (Exception e) {
        e.printStackTrace();
    }
}

В идеале прокси-сервер должен был ответить HTTP 407 Proxy Authentication Required на первоначальный запрос вместо 403 Forbidden. 403 в основном говорит GO-AWAY! В то время как 407 говорит: «Эй, ты хочешь пройти? Назови мне причину, почему?» ответив заголовком «Proxy-Authenticate:», на который вы должны ответить своими учетными данными через заголовок «Proxy-Authorization:».

Выполняя упреждающую аутентификацию, вы, по сути, отправляете учетные данные хосту, когда их не запрашивали, что-то вроде того, что вы прикрепляете свой номер социального страхования большими буквами ко лбу.

EDIT Я думаю, что нашел что-то, что МОЖЕТ помочь вам справиться с этим: HttpClient 4.2.2 и прокси-сервер с именем пользователя/паролем посмотрите, запустит ли это его.

person Dave G    schedule 26.03.2013
comment
Дэйв, спасибо за помощь! Я попробовал этот код, но параметр Proxy-Authorization не был передан, поэтому я все еще получаю 403... - person user2209017; 27.03.2013
comment
Мне интересно, есть ли что-то шаткое в том, что вы проксируете HTTPS через HTTP - person Dave G; 27.03.2013
comment
Хорошо, я копну немного глубже и посмотрю, смогу ли я что-то заметить - person Dave G; 27.03.2013
comment
Можете ли вы предоставить журнал отладки проводов из httpclient apache? будьте осторожны, чтобы замаскировать или заменить любые хэши паролей, которые могут быть в пути. - person Dave G; 28.03.2013
comment
Уровни журнала для отладки org.apache.http, org.apache.http.wire - person Dave G; 28.03.2013
comment
Дэйв, пожалуйста, смотрите выше, я добавил журналы, вы это имели в виду? - person user2209017; 29.03.2013
comment
Что касается прокси - вы им управляете или это юридическое лицо компании? - person Dave G; 29.03.2013
comment
Я внес некоторые изменения в свой ответ, а также немного переформатировал ваш вопрос. - person Dave G; 30.03.2013
comment
Прокси — это сервис, я не могу его контролировать. - person user2209017; 01.04.2013
comment
Дэйв, я выполнил ваш новый код, и теперь он передает заголовок авторизации, который выполняется, к сожалению, прокси-сервер ищет заголовок прокси-аутентификации. Потенциально это может быть изменено на стороне службы, однако моя целевая конечная точка также требует аутентификации и считывает подпись из заголовка авторизации и должна отличаться от аутентификации прокси ... Кстати, большое спасибо за вашу помощь, я не проголосовал за ваш ответ, потому что мне не хватает представителя. Извините! - person user2209017; 01.04.2013
comment
Единственное, что я могу попробовать, это добавить AuthState на прокси-сервере в CHALLENGED в контексте - мое предложение состоит в том, чтобы заставить этот прокси-сервер возвращать 407, чтобы правильно бросить вызов клиенту таким образом, чтобы он автоматически обрабатывал его. К сожалению, у меня нет среды, чтобы проверить эту теорию. - person Dave G; 01.04.2013
comment
Я еще немного покопался в этом - к сожалению, это не работает, как вызов аутентификации 401 - я думаю, вам нужно попытаться упреждающе настроить AuthState и добавить его в созданный локальный контекст. Без ответа 407 от прокси-сервера я не знаю другого способа настроить http-клиент для упреждающей аутентификации прокси-сервера без проблем. - person Dave G; 01.04.2013
comment
Только что проверил - ChallengeState.PROXY работает как заявлено. - person Dave G; 03.04.2013
comment
Большое спасибо! КСТАТИ; вам нужно использовать как минимум версию 4.2 httpclient, чтобы иметь функциональность ChallengeState.PROXY - person user339047; 07.08.2013

Я решил свою проблему, создав собственный прокси на amazon EC2.

Моя цель состояла в том, чтобы иметь возможность получить доступ к службе https, для которой требуется белый список IP-адресов, из приложения, работающего на Heroku, поэтому нет статического IP-адреса или диапазона IP-адресов, которые я мог бы внести в белый список, поэтому мне нужен прокси со статическим IP-адресом.

Я пытался использовать аддон proximo heroku и столкнулся с проблемой, описанной выше.

Спасибо Dave G за помощь!

person user2209017    schedule 03.04.2013