2013-02-25 299 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