Proxy HTTP autenticado con Java

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

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

http.proxyHost= http.proxyPort= https.proxyHost= https.proxyPort= 

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

(EDITAR: Como lo señala el OP, también se requiere el uso de un java.net.Authenticator . Estoy actualizando mi respuesta en consecuencia por razones de corrección).

Para la autenticación, use java.net.Authenticator para establecer la configuración del proxy y establecer 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); 

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.

Él 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 me parece bien.

Modifiqué ligeramente la versión original para usar equalsIgnoreCase () en lugar de equals (host.toLowerCase ()) debido a esto: http://mattryall.net/blog/2009/02/the-infamous-turkish-locale-bug y yo se agregó “80” como valor predeterminado para el puerto para evitar NumberFormatException en Integer.parseInt (port).

Ya casi estás allí, solo tienes que anexar:

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

Pero, al configurar solo esos parámetros, la autenticación no funciona.

Es necesario 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()); } } ); 

La mayoría de la respuesta está 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, acceso a recursos 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, acceso a recursos HTTPS (SSL)

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

Caso 4: Proxy con autenticación de usuario, acceso a recursos HTTPS (SSL)

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

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

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

Caso 6: Proxy con autenticación de usuario, acceso a recursos HTTP y 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 con System.setProperty (“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 usando 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"); 

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

Para Java 1.8 y superior debe configurar

-Djdk.http.auth.tunneling.disabledSchemes =

para hacer proxies con autorización básica trabajando con https junto con Authenticator como se menciona en la respuesta aceptada