2013-02-25 23 views
5

Próbuję połączyć się z serwerem za pośrednictwem protokołu https, który wymaga uwierzytelnienia. Co więcej, mam serwer proxy http w środku, który również wymaga uwierzytelnienia. Używam ProxyAuthSecurityHandler do uwierzytelniania za pomocą proxy i BasicAuthSecurityHandler w celu uwierzytelnienia z serwerem.Nie można tunelować przez serwer proxy. Proxy zwraca "HTTP/1.1 407" przez https

Odbieranie java.io.IOException: Nie można tunelować przez serwer 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) 

Zauważyłem, że realizacja ProxyAuthSecurityHandler spodziewa kod odpowiedzi 407 Jednakże podczas debugowania nigdy nie dostać się do drugiej części ze względu na IOException rzucony.

Kod przystawki:

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

spróbował wykorzystać wink wersje klienckie 1.1.2 oraz 1.2.1. problem powtarza się w obu.

Odpowiedz

3

To, co odkryłem, to że próbując przejść przez serwer proxy przy użyciu adresu https, najpierw wysyłamy CONNECT, a dopiero potem próbujemy wysłać żądanie. Serwer proxy nie może odczytać żadnych nagłówków, które dołączamy do żądania, ponieważ nie ma klucza do odszyfrowania ruchu. Oznacza to, że CONNECT powinien już mieć użytkownika/przekazać proxy, aby przejść ten etap. tutaj jest bardzo prosta kod użyłem - to działa na mnie:

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

    } 
    } 

jeśli używasz oka - jak to zrobić, trzeba ustawić proxy w ClientConfig i przed przekazaniem go do RestClient ustawienie domyślne authentator.

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

Jeśli Ilana Płatonow „s answer nie działa, spróbuj edycji zmiennych:

jdk.http.auth.tunneling.disabledSchemes 
jdk.http.auth.proxying.disabledSchemes 
Powiązane problemy