2013-02-25 301 views
5

我尝试通过需要身份验证的https连接到服务器。此外,我在中间还有一个http代理,它也需要身份验证。我使用ProxyAuthSecurityHandler对代理和BasicAuthSecurityHandler进行身份验证,以便与服务器进行身份验证。无法通过代理隧道。代理通过https返回“HTTP/1.1 407”

接收java.io.IOException:无法隧道通过代理。

Proxy returns "HTTP/1.1 407 Proxy Auth Required" 

at sun.net.www.protocol.http.HttpURLConnection.doTunneling(HttpURLConnection.java:1525) 
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect (AbstractDelegateHttpsURLConnection.java:164) 
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:133) 
at org.apache.wink.client.internal.handlers.HttpURLConnectionHandler.processRequest(HttpURLConnectionHandler.java:97) 

我注意到ProxyAuthSecurityHandler的实现期待的响应代码407但是,调试,我们从来没有得到第二部分是由于抛出IOException异常时。

代码卡:

ClientConfig configuration = new ClientConfig(); 
configuration.connectTimeout(timeout); 

MyBasicAuthenticationSecurityHandler basicAuthProps = new MyBasicAuthenticationSecurityHandler(); 
basicAuthProps.setUserName(user); 
basicAuthProps.setPassword(password); 
configuration.handlers(basicAuthProps); 

if ("true".equals(System.getProperty("setProxy"))) { 
    configuration.proxyHost(proxyHost); 
    if ((proxyPort != null) && !proxyPort.equals("")) { 
     configuration.proxyPort(Integer.parseInt(proxyPort)); 
    } 

    MyProxyAuthSecurityHandler proxyAuthSecHandler = 
      new MyProxyAuthSecurityHandler(); 
    proxyAuthSecHandler.setUserName(proxyUser); 
    proxyAuthSecHandler.setPassword(proxyPass); 
    configuration.handlers(proxyAuthSecHandler); 
} 

restClient = new RestClient(configuration); 
// create the createResourceWithSessionCookies instance to interact with 

Resource resource = getResource(loginUrl); 

// Request body is empty 
ClientResponse response = resource.post(null); 

使用Wink客户端版本1.1.2和1.2.1也试过。这个问题在两个重复。

回答

3

我发现,当试图通过使用https url的代理时,我们首先发送CONNECT,然后尝试发送请求。代理服务器无法读取我们附加到请求的任何头像,导致它没有解密通信的密钥。 这意味着CONNECT应该已经有用户/传给代理来通过这个阶段。 这里是一个代码卡我用 - 为我的作品:

import sun.misc.BASE64Encoder; 
import java.io.*; 
import java.net.*; 

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 = "proxy host"; 
     int proxyport = port; 
     String proxylogin = "proxy username"; 
     String proxypass = "proxy password"; 
     String url = "https://...."; 
     new ProxyPass(proxyhost, proxyport, proxylogin, proxypass, url); 

    } 
    } 

如果您使用的眼色 - 像我这样做,你需要设置在ClientConfig代理,并把它传递给RESTClient实现之前设定的默认认证。

ClientConfig configuration = new ClientConfig(); 
    configuration.connectTimeout(timeout); 

    BasicAuthenticationSecurityHandler basicAuthProps = new BasicAuthenticationSecurityHandler(); 
    basicAuthProps.setUserName(user); 
    basicAuthProps.setPassword(password); 
    configuration.handlers(basicAuthProps); 

    if (proxySet()) { 
     configuration.proxyHost(proxyHost); 
     if ((proxyPort != null) && !proxyPort.equals("")) { 
      configuration.proxyPort(Integer.parseInt(proxyPort)); 
     } 
     Authenticator.setDefault(new Authenticator() { 
      @Override 
      protected PasswordAuthentication getPasswordAuthentication() { 
       if (getRequestorType().equals(RequestorType.PROXY)) { 
        return new PasswordAuthentication(proxyUser), proxyPass.toCharArray()); 
       } 
       return super.getPasswordAuthentication(); 
      } 
     }); 
    } 

    restClient = new RestClient(configuration); 
    Resource resource = getResource(loginUrl); 

    // Request body is empty 
    ClientResponse response = resource.post(null); 
    if (response.getStatusCode() != Response.Status.OK.getStatusCode()) { 
     throw new RestClientException("Authentication failed for user " + user); 
    } 
0

如果Ilana普拉东诺夫answer不行,请尝试编辑变量:

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