2009-10-26 25 views
46

¿Cómo puedo configurar el nombre de usuario y la contraseña para autenticar un servidor proxy http utilizando Java?Proxy HTTP autenticado con Java

Acabo de encontrar los siguientes parámetros de configuración:

http.proxyHost=<proxyAddress> 
http.proxyPort=<proxyPort> 
https.proxyHost=<proxyAddress> 
https.proxyPort=<proxyPort> 

Pero, mi servidor proxy requiere autenticación. ¿Cómo puedo configurar mi aplicación para usar el servidor proxy?

+2

¿Qué tipo de autenticación acepta/requiere su servidor proxy? Basic, Digest o NTLM? – brianegge

Respuesta

65

(EDIT:.. Como se ha señalado por la OP, el uso de un java.net.Authenticator se requiere también que estoy actualizando mi respuesta en consecuencia por el bien de la corrección)

Para la autenticación, utilice java.net.Authenticator para establecer la configuración del proxy y establezca las propiedades del sistema http.proxyUser y http.proxyPassword.

final String authUser = "user"; 
final String authPassword = "password"; 
Authenticator.setDefault(
    new Authenticator() { 
     @Override 
     public PasswordAuthentication getPasswordAuthentication() { 
     return new PasswordAuthentication(
       authUser, authPassword.toCharArray()); 
     } 
    } 
); 

System.setProperty("http.proxyUser", authUser); 
System.setProperty("http.proxyPassword", authPassword); 
+2

Yo también recibí la respuesta con el fragmento de código. Pero cuando establezco los valores incorrectos para la contraseña, si la solicitud pasó por el proxy, debería decir Conexión rechazada. Obtuve el resultado en ese caso también. ¿Cómo puedo verificar si las solicitudes se envían a través del proxy? – divinedragon

+0

@Pascal: creo que se refería a esas dos últimas líneas para establecer 'proxyHost' y' proxyPort', no 'proxyUser' y' proxyPassword', ya que estas últimas ya están establecidas por el Authenticator. ¿O me estoy perdiendo algo? –

+0

@divinedragon No debería decir "conexión rechazada". Ni siquiera es posible. La conexión fue aceptada por TCP, al proxy, que luego falló su autenticación. En ese punto, es imposible que el proxy genere un rechazo de conexión. – EJP

23

Ya casi ha terminado, sólo hay que añadir:

-Dhttp.proxyUser=someUserName 
-Dhttp.proxyPassword=somePassword 
10

embargo, el establecimiento de parámetros sólo eso, la autenticación no hacen obras.

son necesarias para agregar a ese código lo siguiente:

final String authUser = "myuser"; 
final String authPassword = "secret"; 

System.setProperty("http.proxyHost", "hostAddress"); 
System.setProperty("http.proxyPort", "portNumber"); 
System.setProperty("http.proxyUser", authUser); 
System.setProperty("http.proxyPassword", authPassword); 

Authenticator.setDefault(
    new Authenticator() { 
    public PasswordAuthentication getPasswordAuthentication() { 
     return new PasswordAuthentication(authUser, authPassword.toCharArray()); 
    } 
    } 
); 
+0

No es necesario que agregue el Authenticator. Para mí, con Java 7 y Java 8 es suficiente para establecer las propiedades http. *. –

3

probar este corredor que escribí. Podría ser útil

import java.io.InputStream; 
import java.lang.reflect.Method; 
import java.net.Authenticator; 
import java.net.PasswordAuthentication; 
import java.net.URL; 
import java.net.URLConnection; 
import java.util.Scanner; 

public class ProxyAuthHelper { 

    public static void main(String[] args) throws Exception { 
     String tmp = System.getProperty("http.proxyUser", System.getProperty("https.proxyUser")); 
     if (tmp == null) { 
      System.out.println("Proxy username: "); 
      tmp = new Scanner(System.in).nextLine(); 
     } 
     final String userName = tmp; 

     tmp = System.getProperty("http.proxyPassword", System.getProperty("https.proxyPassword")); 
     if (tmp == null) { 
      System.out.println("Proxy password: "); 
      tmp = new Scanner(System.in).nextLine(); 
     } 
     final char[] password = tmp.toCharArray(); 

     Authenticator.setDefault(new Authenticator() { 
      @Override 
      protected PasswordAuthentication getPasswordAuthentication() { 
       System.out.println("\n--------------\nProxy auth: " + userName); 
       return new PasswordAuthentication (userName, password); 
      } 

     }); 

     Class<?> clazz = Class.forName(args[0]); 
     Method method = clazz.getMethod("main", String[].class); 
     String[] newArgs = new String[args.length - 1]; 
     System.arraycopy(args, 1, newArgs, 0, newArgs.length); 
     method.invoke(null, new Object[]{newArgs}); 
    } 

} 
26

http://rolandtapken.de/blog/2012-04/java-process-httpproxyuser-and-httpproxypassword dice:

Otros sugieren utilizar un autenticador predeterminado personalizado. Pero eso es peligroso porque enviará su contraseña a cualquiera que pregunte.

Esto es relevante si algunas solicitudes http/https no pasan por el proxy (lo cual es bastante posible dependiendo de la configuración). En ese caso, enviaría sus credenciales directamente a algún servidor http, no a su proxy.

Sugiere la siguiente solución.

// Java ignores http.proxyUser. Here come's the workaround. 
Authenticator.setDefault(new Authenticator() { 
    @Override 
    protected PasswordAuthentication getPasswordAuthentication() { 
     if (getRequestorType() == RequestorType.PROXY) { 
      String prot = getRequestingProtocol().toLowerCase(); 
      String host = System.getProperty(prot + ".proxyHost", ""); 
      String port = System.getProperty(prot + ".proxyPort", "80"); 
      String user = System.getProperty(prot + ".proxyUser", ""); 
      String password = System.getProperty(prot + ".proxyPassword", ""); 

      if (getRequestingHost().equalsIgnoreCase(host)) { 
       if (Integer.parseInt(port) == getRequestingPort()) { 
        // Seems to be OK. 
        return new PasswordAuthentication(user, password.toCharArray()); 
       } 
      } 
     } 
     return null; 
    } 
}); 

No lo he probado todavía, pero a mí me parece bien.

he modificado la versión original ligeramente utilizar equalsIgnoreCase() en lugar de iguales (host.toLowerCase()) debido a esto: http://mattryall.net/blog/2009/02/the-infamous-turkish-locale-bug y yo añadió "80" como el valor predeterminado para el puerto para evitar NumberFormatException en Integer.parseInt (Puerto).

7

La mayoría de las respuestas están ahí, pero para mí no del todo. Esto es lo que funciona para mí con java.net.HttpURLConnection (he probado todos los casos con JDK 7 y JDK 8). Tenga en cuenta que no tiene que usar la clase Authenticator.

Caso 1: Proxy sin autenticación de usuario, recursos de acceso HTTP

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport 

Caso 2: Proxy con autenticación de usuario, acceso a recursos HTTP

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass 

Caso 3: Proxy sin autenticación de usuario, el acceso HTTPS recursos (SSL)

-Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport 

Caso 4: Proxy con el usuario au thentication, recursos de acceso HTTPS (SSL)

-Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass 

Caso 5: Proxy sin autenticación de usuario, el acceso HTTP y HTTPS recursos (SSL)

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport 

Caso 6: Proxy con autenticación de usuario, el acceso HTTP y los recursos HTTPS (SSL)

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttp.proxyUser=myuser -Dhttp.proxyPassword=mypass -Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass 

puede establecer las propiedades en el System.setProperty con ("clave", "valor) también.

Para acceder al recurso HTTPS, puede que tenga que confiar en el recurso descargando el certificado del servidor y guardándolo en un almacén de confianza y luego utilizando ese almacén de confianza. es decir

System.setProperty("javax.net.ssl.trustStore", "c:/temp/cert-factory/my-cacerts"); 
System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 
+1

Puedo confirmar que no es necesario usar la clase Authenticator en JDK 7 o 8. Simplemente use '-D .proxyUser =' y '-D .proxyPassword ='. –

+0

Gracias por la edición @Cristiano –

1

Para Java 1.8 y superior debe establecer

-Djdk.http.auth.tunneling.disabledSchemes =

hacer proxies con autorización básica trabajar con https, junto con Autenticador como se menciona en la respuesta aceptada