Невозможно проложить туннель через прокси. Прокси возвращает "HTTP/1.1 407" через https

Я столкнулся с любопытным поведением java6/8. Я пытаюсь туннелировать через прокси, который нуждается в базовой аутентификации пользователя. Делать это стандартным Java-аутентификатором. Если я пытаюсь получить доступ к URL-адресу https в качестве первого URL-адреса, возникает исключение:

java.io.IOException: Невозможно туннелировать через прокси. Прокси-сервер возвращает "HTTP/1.1 407 Proxy Authentication Required"

Но если я сначала получаю доступ к URL-адресу http, а затем к URL-адресу https, то доступ https работает нормально.

Учитывая этот код:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.URL;

public class ProxyPass {
    public ProxyPass( String proxyHost, int proxyPort, final String userid, final String password, String url ) {

    try {
            /* Create a HttpURLConnection Object and set the properties */
            URL u = new URL( url );
            Proxy proxy = new Proxy( Proxy.Type.HTTP, new InetSocketAddress( proxyHost, proxyPort ) );
            HttpURLConnection uc = (HttpURLConnection) u.openConnection( proxy );

            Authenticator.setDefault( new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    if (getRequestorType().equals( RequestorType.PROXY )) {
                        return new PasswordAuthentication( userid, password.toCharArray() );
                    }
                    return super.getPasswordAuthentication();
                }
            } );
            uc.connect();
            /* Print the content of the url to the console. */
            showContent( uc );
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void showContent( HttpURLConnection uc ) throws IOException {
        InputStream i = uc.getInputStream();
        char c;
        InputStreamReader isr = new InputStreamReader( i );
        BufferedReader br = new BufferedReader( isr );
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println( line );
        }
    }

    public static void main( String[] args ) {
        String proxyhost = "proxyHost";
        int proxyport = proxyPort;
        final String proxylogin = proxyUser;
        final String proxypass = proxyPass;

        String url = "http://www.google.de";
        String surl = "https://www.google.de";

//            new ProxyPass( proxyhost, proxyport, proxylogin, proxypass, url );  // uncomment this line to see that the https request works!
//            System.out.println( url + " ...ok" );   // uncomment this line to see that the https request works!
        new ProxyPass( proxyhost, proxyport, proxylogin, proxypass, surl );
        System.out.println( surl + " ...ok" );
    }

Есть предложения, идеи?

2 ответа

Решение

Вы должны отредактировать переменныеjdk.http.auth.tunneling.disabledSchemes и jdk.http.auth.proxying.disabledSchemes так, чтобы они были пустыми:

jdk.http.auth.tunneling.disabledSchemes=
jdk.http.auth.proxying.disabledSchemes=

В моем случае я нашел в этом файле

jdk1.8.0_111/ JRE / Библиотека /net.properties

Изменения в Java 8 Обновление 111:

Теперь прокси, требующие базовой аутентификации при настройке туннеля для HTTPS, больше не будут работать по умолчанию. При необходимости эту схему проверки подлинности можно повторно активировать, удалив Basic из сетевого свойства jdk.http.auth.tunneling.disabledSchemes или установив системное свойство с тем же именем на "" (пустое) в командной строке.

http://www.oracle.com/technetwork/java/javase/8u111-relnotes-3124969.html

Ваши варианты:

  • решить проблему (в целях безопасности), обновив схему аутентификации вашего прокси, например, для дайджест-аутентификации доступа
  • или просто обойти проблему, запустив Java с

    java -Djdk.http.auth.tunneling.disabledSchemes=""
    

Это может быть полезно:

System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "false");
System.setProperty("jdk.http.auth.proxying.disabledSchemes", "false");
Другие вопросы по тегам