Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中无法将代理身份验证与Https一起使用_Java_Https_Proxy_Httpurlconnection - Fatal编程技术网

在Java中无法将代理身份验证与Https一起使用

在Java中无法将代理身份验证与Https一起使用,java,https,proxy,httpurlconnection,Java,Https,Proxy,Httpurlconnection,说明 我正在尝试通过需要身份验证的代理连接到使用https的web服务器,但它不起作用 HttpsURLConnection类在没有«代理授权»头的情况下发送第一个打开隧道的请求,即使是强制的 在这种情况下,服务器将返回«需要407代理验证» 重现问题的代码 public class TestProxy { @Test public void testOne() throws IOException { final String PROXY_USERNAME = "usern

说明

我正在尝试通过需要身份验证的代理连接到使用https的web服务器,但它不起作用

HttpsURLConnection类在没有«代理授权»头的情况下发送第一个打开隧道的请求,即使是强制的

在这种情况下,服务器将返回«需要407代理验证»

重现问题的代码

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()方法引起的 它在不添加«代理授权»头的情况下创建新的«连接请求»

解决方法

解决方法是首先连接到http地址,这样代理服务器将注册用户代理并授权连接,而无需添加代理授权标头


jdk版本是1.8.0_181-b13。

要通过代理使用https连接到webservice,我们需要禁用系统属性

这仅适用于jdk>8u11

在应用程序中设置系统权限将不起作用

  private void allowAuthenticationForHttps() {
    System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
  }
它应该作为一个标志在命令行中传递

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