2013-02-25 17 views
5

Tôi cố gắng kết nối với máy chủ qua https yêu cầu xác thực. Hơn nữa, tôi có một proxy http ở giữa cũng yêu cầu xác thực. Tôi sử dụng ProxyAuthSecurityHandler để xác thực với proxy và BasicAuthSecurityHandler để xác thực với máy chủ.Không thể đường hầm qua proxy. Proxy trả về "HTTP/1.1 407" qua https

Nhận java.io.IOException: Không thể truyền qua proxy.

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) 

Tôi nhận thấy rằng việc triển khai ProxyAuthSecurityHandler đang chờ mã phản hồi 407 tuy nhiên, trong khi gỡ lỗi, chúng tôi không bao giờ nhận được phần thứ hai do IOException được ném.

Mã snap:

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

Cố gắng sử dụng các phiên bản client nháy mắt 1.1.2 và 1.2.1 cũng. vấn đề lặp lại trong cả hai.

Trả lời

3

Điều tôi phát hiện ra là khi cố gắng chuyển qua proxy bằng url https, trước tiên chúng tôi gửi CONNECT và chỉ sau đó thử gửi yêu cầu. Máy chủ proxy không thể đọc bất kỳ phần đầu nào mà chúng tôi đính kèm theo yêu cầu, vì nó không có khóa để giải mã lưu lượng truy cập. Điều này có nghĩa là CONNECT đã có người dùng/vượt qua proxy để vượt qua giai đoạn này. đây là một snap mã tôi sử dụng - mà làm việc cho tôi:

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

    } 
    } 

nếu bạn đang sử dụng nháy mắt - như tôi làm, bạn cần phải thiết lập proxy trong ClientConfig và trước khi đi qua nó vào RestClient thiết lập mặc định người xác thực.

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

Nếu Ilana Platonov 's answer không hoạt động, hãy thử chỉnh sửa các biến:

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