Java 无法通过代理建立隧道。代理通过 https 返回“HTTP/1.1 407”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41505219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:26:44  来源:igfitidea点击:

Unable to tunnel through proxy. Proxy returns “HTTP/1.1 407” via https

javaauthenticationhttpsproxytunnel

提问by PPr

I am faced with a curious behaviour of java6/8. I try to tunnel through a proxy which needs basic user authentication. Doing this by the standard java Authenticator. If I try to access a https url as the first url, an exception is thrown:

我面临着 java6/8 的奇怪行为。我尝试通过需要基本用户身份验证的代理进行隧道传输。由标准的 java Authenticator 执行此操作。如果我尝试访问 https url 作为第一个 url,则会引发异常:

java.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.1 407 Proxy Authentication Required"

java.io.IOException:无法通过代理建立隧道。代理返回“需要 HTTP/1.1 407 代理身份验证”

But if I access a http URL first and then the https URL, the https access works fine.

但是,如果我先访问 http URL,然后访问 https URL,则 https 访问工作正常。

Given that code:

鉴于该代码:

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" );
    }

Any suggestions, ideas?

任何建议,想法?

采纳答案by linhadiretalipe

You have to edit the variables jdk.http.auth.tunneling.disabledSchemesand jdk.http.auth.proxying.disabledSchemesto blank like this:

您必须将变量jdk.http.auth.tunneling.disabledSchemesjdk.http.auth.proxying.disabledSchemes编辑 为空白,如下所示:

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

In my case I found in this file

就我而言,我在这个文件中找到了

jdk1.8.0_111/jre/lib/net.properties

jdk1.8.0_111/jre/lib/net.properties

回答by Marcus

Change in Java 8 Update 111:

Java 8 Update 111 中的更改:

Now, proxies requiring Basic authentication when setting up a tunnel for HTTPS will no longer succeed by default. If required, this authentication scheme can be reactivated by removing Basic from the jdk.http.auth.tunneling.disabledSchemes networking property, or by setting a system property of the same name to "" ( empty ) on the command line.

现在,默认情况下,在为 HTTPS 设置隧道时需要基本身份验证的代理将不再成功。如果需要,可以通过从 jdk.http.auth.tunneling.disabledSchemes 网络属性中删除 Basic 或通过在命令行上将同名的系统属性设置为 ""(空)来重新激活此身份验证方案。

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

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

Your options:

您的选择:

  • solve the issue (for the sake of security) by upgrading the authentication scheme of your proxy, e.g. to Digest access authentication
  • or just workaround the issue by running Java with

    java -Djdk.http.auth.tunneling.disabledSchemes=""
    
  • 通过升级代理的身份验证方案来解决问题(为了安全起见),例如摘要访问身份验证
  • 或者只是通过运行 Java 来解决这个问题

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